{"id":30330088,"url":"https://github.com/kayr/xform-markup-editor","last_synced_at":"2025-10-29T00:13:05.487Z","repository":{"id":38751797,"uuid":"51291601","full_name":"kayr/xform-markup-editor","owner":"kayr","description":"Simple text based xform Generator and Editor for Open Data Kit and OpenXData","archived":false,"fork":false,"pushed_at":"2020-10-13T02:32:50.000Z","size":1445,"stargazers_count":9,"open_issues_count":6,"forks_count":4,"subscribers_count":5,"default_branch":"master","last_synced_at":"2023-03-24T07:02:52.464Z","etag":null,"topics":["odk","openxdata-xform","oxd","xform-generator","xforms","xml","xpath"],"latest_commit_sha":null,"homepage":null,"language":"Groovy","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kayr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-02-08T10:30:11.000Z","updated_at":"2022-09-07T01:24:06.000Z","dependencies_parsed_at":"2022-08-25T07:14:10.727Z","dependency_job_id":null,"html_url":"https://github.com/kayr/xform-markup-editor","commit_stats":null,"previous_names":[],"tags_count":null,"template":null,"template_full_name":null,"purl":"pkg:github/kayr/xform-markup-editor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kayr%2Fxform-markup-editor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kayr%2Fxform-markup-editor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kayr%2Fxform-markup-editor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kayr%2Fxform-markup-editor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kayr","download_url":"https://codeload.github.com/kayr/xform-markup-editor/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kayr%2Fxform-markup-editor/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270932698,"owners_count":24670250,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-18T02:00:08.743Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["odk","openxdata-xform","oxd","xform-generator","xforms","xml","xpath"],"created_at":"2025-08-18T02:08:25.424Z","updated_at":"2025-10-29T00:13:00.448Z","avatar_url":"https://github.com/kayr.png","language":"Groovy","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Xform Markup Editor For ODK(Javarosa) and OpenXData XForms\n\nYou can generate an [openXdata](http://www.openxdata.org/) or [Open Data Kit(ODK)](https://opendatakit.org/) forms using this editor fast and easy.\n\n### Screenshots\n\n#### Main window\n![Editor][main_window]\n\n#### XML Preview\n![Editor][show_xml]\n\n\n**Table of Contents**\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n\n  - [Download](#download)\n  - [Screenshots](#screenshots)\n    - [Main window](#main-window)\n    - [XML Preview](#xml-preview)\n  - [Features:](#features)\n  - [Instructions](#instructions)\n    - [Adding Appearance To Questions](#adding-appearance-to-questions)\n    - [Adding pages(High Level Groups)](#adding-pageshigh-level-groups)\n    - [Adding Groups(Inner groups with in pages)](#adding-groupsinner-groups-with-in-pages)\n    - [Adding Appearance To Pages/Groups](#adding-appearance-to-pagesgroups)\n    - [Single Select and Multiple Select](#single-select-and-multiple-select)\n    - [Repeat Questions](#repeat-questions)\n    - [Dynamic Single Select or Cascading Select Questions](#dynamic-single-select-or-cascading-select-questions)\n      - [Option 1](#option-1)\n      - [Option 2](#option-2)\n    - [Setting Datatype](#setting-datatype)\n    - [Setting Other question attributes(Required/Hidden/Locked)](#setting-other-question-attributesrequiredhiddenlocked)\n    - [Assigning an Id to a form](#assigning-an-id-to-a-form)\n    - [Assigning ids or binds to questions](#assigning-ids-or-binds-to-questions)\n    - [Adding hints/help text to questions](#adding-hintshelp-text-to-questions)\n    - [Adding styles to forms](#adding-styles-to-forms)\n    - [Adding Arbitrary Bind Attributes and Layout Attributes(e.g appearance)](#adding-arbitrary-bind-attributes-and-layout-attributeseg-appearance)\n      - [A compatibility note about OpenXdata generated XForm and Layout/Bind Attributes (OpenXdata Users Only)](#a-compatibility-note-about-openxdata-generated-xform-and-layoutbind-attributes-openxdata-users-only)\n    - [Multiline Questions/Options](#multiline-questionsoptions)\n    - [Numbering The Questions Automatically](#numbering-the-questions-automatically)\n- [Adding Skip/Validation/Calculation Logic](#adding-skipvalidationcalculation-logic)\n    - [Adding Skip Logic](#adding-skip-logic)\n    - [Adding Validation Logic](#adding-validation-logic)\n    - [Adding Calculation Logic](#adding-calculation-logic)\n  - [Explaining preferences](#explaining-preferences)\n    - [ODK Specific](#odk-specific)\n    - [Openxdata specific](#openxdata-specific)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n### Download\n\nA [download](https://github.com/kayr/xform-markup-editor/releases) of the editor is available [here](https://github.com/kayr/xform-markup-editor/releases).\nTo run this app open the command line and execute `java -jar \u003cfile-name\u003e`\n\n\n\n\n### Features:\n - Simple XPath Variable references e.g instead of `/instance/path_id` you use `$path_id`\n - On the fly simple validation of xpath\n - Direct preview in enketo\n - Integrated ODK Validate\n - Autocompletion of words using Ctrl-K\n - Easy creation of cascading selects by referencing a CSV. The CSV will data will be baked into the generated XFORM.\n - Auto-numbering of labels and IDS\n - Adding arbitrary layout and bind attributes using `@bind:\u003cbindParameter\u003e value` or `@layout:\u003clayoutParameter\u003e value`\n - If you are designing forms for OpenXData you can select the *Emulate OXD to ODK* preference to convert OXD Xpath to ODK.\n   e.g `$multiselect_qn = 'option'` is converted to `selected($multiselect_qn,'option')`\n - Multiline Questions which make it easier to write markdown spanning multiple lines\n - Support for appearance\n - Support for form styles\n - Some simple constructs while writing skip logic (see [Adding Skip Logic](#adding-skip-logic))\n\n### Instructions\n\nYou start with entering the study name which starts with ***###***\n\nFollowed by the form name which starts with ***##***\n\nFollowed by the questions (one question per line).\n\nWhen you are done simply click the *Show ODK XML* or *Show OXD XML* button to view the XFORM source code.\n\nE.g\n\n```\n### Sample Study\n\n## Sample form\n\nFirst name\n\nSecond name\n\nSex\n\nAge\n\nIs pregnant\n\nDrugs taken\n\n'''This is a question\nthat spans\nmultiple lines '''\n\n```\n\n\n#### Adding Appearance To Questions\nYou can add appearance to any element(groups,pages and questions) using the ***\"@appearance\"*** attribute\n\nLook at [this](http://xlsform.org/ref-table/) page for most supported appearances for both enketo and odk\n\ne.g\n```\n@appearance w1\nQuestion one\n\n@appearance search\nSelect preferences\n \u003e Option 1\n \u003e Option 2\n \u003e Option 3\n \u003e Option 4\n \u003e Option 5\n \u003e Option 6\n```\n\n\nThe above will generate a study named **Sample Study** containing one Form(Sample Form). All questions will be of type Text\n\n#### Adding pages(High Level Groups)\nTo add a page use the **#\u003e \u003cPage.Name\u003e** marker. The example below generates two pages ***Bio Info Page*** and ***Health Status Page***. Pages normally translate to groups. That is high level groups.\n\n```\n### Sample Study\n\n## Sample form\n\n#\u003e Bio Info Page\n\nFirst name\n\nSecond name\n\nSex\n\nAge\n\n#\u003e Health Status Page\n\nIs pregnant\n\nDrugs taken\n\n```\n\n\n\n\n#### Adding Groups(Inner groups with in pages)\n\nYou can wrap questions in a group using the ***group{}*** tag. Only groups that have ids will be labeled with numbers in case you select the ***\"number labels\"*** or ***\"number ids\"*** option.\nE.g :\n```\n### study\n\n## form\n\n#\u003e page one(outer group)\n\nQuestion one\n\n@appearance field-list\ngroup{ This is a group label but its optional\n   Question two\n   Question three\n}\n```\n\nYou can assign appearance,skiplogic and ids to these groups too\nE.g:\n```\n@appearance field-list\n@id nested_group\ngroup{ This is a group label but its optional\n   Question two\n   Question three\n}\n```\n\n#### Adding Appearance To Pages/Groups\n\nYou can assign appearance,skiplogic and ids to these pages\nE.g:\n```\n@appearance field-list\n@id bio_info_page\n#\u003e Bio Info Page\n\n@appearance field-list\n@id nested_group\ngroup{ This is a group label but its optional\n   Question two\n   Question three\n}\n```\n\n#### Single Select and Multiple Select\nTo add options to questions you simply use `\u003e` or `\u003e\u003e` for single select and multiple select respectively\n\nE.g To add *single select options* to the [Sex] Question\n\n```\nSex\n\u003emale\n\u003efemale\n```\nand *to add multiple select options* to the [Drugs taken] Question\n\n```\nDrugs taken\n\u003e\u003ePain killers\n\u003e\u003eAntibiotics\n```\n'''You can assign variables to the options too'''\n\ne.g \"\u003e\u003e $pain_killers Pain Killers\" will assign variable '''pain_killers''' to this option\n\n\n\n\n#### Repeat Questions\nE.g\n\n```\nrepeat{ Child details\n\n  Child Name\n\n  Child Sex\n\n  Child Age\n}\n```\n#### Dynamic Single Select or Cascading Select Questions\nDynamic questions are questions whose options change dynamically depending on other questions input.\n\n##### Option 1\n\nTo make these you just have to create a CSV file(may be in excel) then paste the content in the markup editor wrapped in the '''dynamic{ }''' tag.  If you wish to make the questions required add a \"'''*\"''' at the beginning of question header. In the example below region is required. E.g\n\n```\ndynamic{\n*Region,\tSub-Region,\t    City\nWashington,\tKing,\t    Seattle\nWashington,\tKing,\t    Redmond\nTexas,\t    King-Texas,\tDumont\nTexas,\t    King-Texas,\tFinney\nTexas,\t    Cameron,\tharlingen\nAfrica,\t    Uganda,\t    Kampala\nAfrica,\t    Uganda,\t    Masaka\nAfrica,\t    Kenya,\t    Kisumu\nAfrica,\t    Kenya,\t    Eldoret\nEurope,\t    Netherlands,Netherlandis\nEurope,\t    Netherlands,Another Netherlands\n}\n```\n\n##### Option 2\n\nYou can save the CSV as an independent file then import it with the '''csv:import''' syntax\n\nE.g\n\n```\ncsv:import RelativePathToCsvFile.csv\n```\n#### Setting Datatype\nIf you wish to specify data types on the question you just need to add a datatype attribute just before the question.\n\nE.g To make the question [Age] accept numbers only you do as below\n\n```\n@number\nAge\n```\nOther datatypes include @number, @decimal, @date, @boolean, @time, @datetime, @picture, @video, @audio, @picture, @gps, @barcode\n\n#### Setting Other question attributes(Required/Hidden/Locked)\nTo make a question required you add a '''*''' at the beginning of the question\n\nE.g To make question ***First name*** *required*\n\n```\n*First name\n```\nor\n\n```\n@required\nFirst name\n```\nTo make it ***hidden***\n\n```\n@invisible\nFirst name\n```\nTo make it ***locked or read only***\n\n```\n@readonly\nFirst name\n```\n#### Assigning an Id to a form\nTo assign an id to a form use the ***@id*** attribute\n\nE.g\n```\n@id this_is_a_custom_id\n## Simple form\n```\n\n#### Assigning ids or binds to questions\nSometimes questions have very long bindings or ids and need to be shortened(in order to be exported).Or sometimes you need to assign a question an id if you plan to use it as a reference in skip or validation logic.\n\nTo assign an id to a question use the ***@id*** attribute\n\nE.g\n\n```\n@id first_name\nFirst name\n```\nOnly lowercase id names are allowed followed by a mix of numbers and underscores like ***first_name_1*** but not ***1_first_name***\n\n#### Adding hints/help text to questions\nYou can add a hint or help text using the ***@hint*** attribute like this\n\nE.g\n\n```\n@hint This is help text for first name question\nFirst name\n```\n#### Adding styles to forms\nYou can add styles to forms.\nE.g Adding the theme-grid style to a form\n```\n### study\n\n@style theme-grid\n## form name\n\n#\u003e page one\n```\n\n#### Adding Arbitrary Bind Attributes and Layout Attributes(e.g appearance)\nYou can add layout attributes(like appearance,jr:count etc) to questions. See below:\n\nE.g\nTo make a select-one question with search\n```\n@appearance search\nSelect one option\n \u003eoption one\n \u003eoption two\n \u003eoption three\n \u003eoption four\n```\n\nIf you wish to add any other custom layout attribute you can use the ***\"@layout:...\"*** syntax\nE.g The same example below is the same as the one above\n```\n@layout:appearance search\nSelect one option\n \u003eoption one\n \u003eoption two\n \u003eoption three\n \u003eoption four\n```\n\nTo preload the username configured in ODK Collect settings page do the following. These properties will be added to the bind section of the xform\n```\n@bind:jr:preload property\n@bind:jr:preloadParams username\n@readonly\nUser name\n```\n\n##### A compatibility note about OpenXdata generated XForm and Layout/Bind Attributes (OpenXdata Users Only)\nOpenXdata Form Designer does not support layout and bind attributes and therefore these attributes will disappear once you load the form into the openxdata form designer. To work around this, in the editor select the ***Store extra attributes in Comment***  preference then these attributes will be embedded into the hint section of a question. This is important when you are using this editor's library as a bridge between OpenXdata and OpenDataKit. When converting an openXdata xform to OpenDataKit XForm these attributes will be picked up and reinserted into the form.\n\n\n#### Multiline Questions/Options\n\nTo write questions that span multiple lines, simply wrap the question text in triple quotes. This makes it easy to write Markdown\n\nE.g\n```\n'''This is a question\nthat spans\nmultiple lines '''\n```\n\nYou can also have options that span multiple line\n\nE.g\n```\n'''\nQuestion text\n\u003e '''This is an option\nthat spans multiple lines'''\n\u003eOption 1\n```\n\n\n#### Numbering The Questions Automatically\n\nTo number the questions automatically check the ***Number Labels checkbox*** on the toolbar. If you want the numbers to be propagated to the binding then you can also check the ***Preferences -\u003e Number IDs checkbox***.\n\n**N.B** Selecting the ***number ids option*** has one downside in that when a question is added to a form.. all following questions after that question will get a new bindings and hence might make it difficult to analyze data between two form versions.\n\n## Adding Skip/Validation/Calculation Logic\nBefore the markup editor was for basically generating form content(questions) and groups but it was extended to also support adding of skip/validation/calculation logic. This comes in a little handy if you have to write complex formulas only handled by xforms clients that visual form designers cannot handle. You get a little benefit of basic validation of your formulas and variables. All the formulas are based on plain XPATH syntax. But with simpler question referencing as compared to the raw XML way.\n\n***Referencing question IDs:*** You reference a question in a formula like this ***$\\\u003cquestion-id\\\u003e***. To reference the current question variable use the ***\".\"***\n\nIn special circumstances you may want to use ***$.*** to reference the current question, this is because in the generated xform XML the \"***$.***\" will be replaced by the current question binding which looks like this /forminstance/questionvariable. It is rare for that you will ever need to use \"***$.***\" usually the dot(.) is enough.\n\n***Note: it is advised you assign ids to all questions that are going to be referenced in your XPATH formulas***\n\nFor this section we will refer to the form below. Note that some of the options have assigned ids or variables. Look at the female option for the Sex question, it has an assigned option variable \"female_opt\"\n\n```\n### Sample Study\n\n\n## Sample form\n\n\nFirst name\n\n\nSecond name\n\n\n@id sex\nSex\n\u003eMale\n\u003e$female Female\n\n@number\nAge\n\n\nIs pregnant\n\n\n@id children\nNumber of children\n\n@id pain_killers\n@number\nPain killers taken\n\n\n@id antibiotics\n@number\nAntibiotics taken\n\n\nTotal drugs taken\n\nrepeat{ Child details\n\n  Child Name\n\n  Child Sex\n}\n```\n#### Adding Skip Logic\n  An example that ***shows*** the [Is pregnant] question when selected sex is female\n\n```\n@showif $sex = 'female'\nIs pregnant\n```\nAn example that ***enables*** the [Is pregnant] question when selected sex is female. In Javarosa clients this behaves the same as @showif\n\n```\n@enableif $sex = 'female'\nIs pregnant\n```\nYou can even even ***hide***  the question if the person is male.\ne.g\n```\n@hideif $sex = 'male'\nIs pregnant\n```\nFor Javarosa clients the above example will be converted to ```relevant=not($sex = 'male')``` after the xform is compiled\n\nOther supported skip logic actions include  ***@hideif, @enableif, @disableif, @showif***\n\n#### Adding Validation Logic\nAn example that makes sure age is between 10 and 20\n\n```\n@validif . \u003e= 10 and . \u003c= 20\n@message Age should be between 10 and 20 years\n@number\nAge\n```\nThe dot(.) means current question The @message attribute sets the message when the validation fails. In this case the message is [Age should be between 10 and 20 years]\n\nValidating a repeat has the correct number of children rows\n\n```\n@validif length(.) = $children\nrepeat{ Child details\n\n  Child Name\n\n  Child Sex\n}\n```\n\nFor Javarosa Client You use jr:count,however the above can be converted to the javarosa(see [Explaining preferences Emulate ODK to OXD ](#explaining-preferences) )\n```\n@jrcount $children\nrepeat{ Child details\n\n  Child Name\n\n  Child Sex\n}\n```\n#### Adding Calculation Logic\nAn example that calculates that total drugs taken i.e [Pain killers taken] + [Antibiotics taken]\n\n```\n@calculate $antibiotics + $pain_killers\nTotal drugs taken\n```\n\n\n### Explaining preferences\n  - **Number Labels:** This auto numbers all the question labels and groups(excludes groups without ids)\n  - **Number Id:** The propagates the label numbers down to the question bindings\n  - **Allow Invalid OXD ids:** The informs the edit to allow all valid XML ids. Without this option selected only lower case ids or bindings are allowed\n  - **Ensure unique Identifier Question:** This checks the a form has a unique identifier exists in a form. This question will generate a unique id that will be explicitly unique to any form instance or data. Uncheck this option to turn off the feature\n\n#### ODK Specific\n  - **Emulate ODK to OXD:** This makes the editor behave as if its converting oxd forms to ODK. It makes extra effort to ensure that oxd xpath retains the semantics when converted to ODK. especially expressions that contain multi select and single select references.\n\t  - This mode also makes any date related question with id of `endtime` to become an automatic time stamp i.e it adds the required jr:preload attributes\n\t  - This add `jr:count` to all repeat questions that have a validation like `length(.) = \u003cvalue\u003e`\n  - **Automatically add meta InstanceID:** This auto add the meta/instanceID element to the form as required by some javarosa clients and servers\n\n#### Openxdata specific\n  - **Generate Layout:** Generates layout xml when you export  form\n  - **Store extra attributes in comments:** OpenXdata Form Designer does not support layout and bind attributes and therefore these attributes will disappear once you load the form into the openxdata form designer. To work around this, in the editor select the ***Store extra attributes in Comment***  preference then these attributes will be embedded into the hint section of a question.\n\n[main_window]: https://github.com/kayr/xform-markup-editor/blob/master/images/main_window.gif?raw=true\n[show_xml]: https://github.com/kayr/xform-markup-editor/blob/master/images/show_xml.PNG?raw=true\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkayr%2Fxform-markup-editor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkayr%2Fxform-markup-editor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkayr%2Fxform-markup-editor/lists"}