<?xml version="1.0" encoding="utf-8"?><article xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0-subset Balisage-1.5" xml:id="helloder">

  <title>Designing a Notation Using ixml</title>
  <info>
    <confgroup>
      <conftitle>Balisage: The Markup Conference 2026</conftitle>
      <confdates>August 3-7, 2026</confdates>
   </confgroup> 
     <abstract>
	<para>
	   The original design of ixml did not focus on converting text files
	   into particular XML document types, but converting them to some
	   XML document type for further transformation. However, the other
	   direction is possible: if you have a particular document type, you
	   can design a textual notation for it. This paper treats a
	   particular use case, in order to reveal some of the options and
	   techniques available to designers of such a notation.
	</para>
     </abstract>
     <author>
	<personname>
           <firstname>Steven</firstname>
           <surname>Pemberton</surname>
	</personname>
	<personblurb>
	   <para>
	      Steven Pemberton is a researcher affiliated with CWI,
	      Amsterdam. His research is in interaction, and how the
	      underlying software architecture can support users.
	   </para>
	   <para>He co-designed the ABC programming language that formed
	   the basis for Python and was one of the first handful of
	   people on the open internet in Europe, when the CWI set it up
	   in 1988. Involved with the Web from the beginning, he
	   organised two workshops at the first Web Conference in
	   1994. For the best part of a decade he chaired the W3C HTML
	   working group, and has co-authored many web standards,
	   including HTML, XHTML, CSS, XForms and RDFa. He now chairs
	   the W3C XForms and Invisible Markup groups.
	   In 2022, ACM SIGCHI awarded him the Lifetime Practice Award.
	   More details at https://www.cwi.nl/~steven
	   </para>
	</personblurb>
	<affiliation>
	   <jobtitle>Researcher</jobtitle>
	   <orgname>CWI, Amsterdam</orgname>
	</affiliation>
	<email>steven.pemberton@cwi.nl</email>
	<link xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">http://cwi.nl/~steven/</link>
     </author>
<legalnotice><para>© Steven Pemberton, 2026</para></legalnotice>
     <keywordset role="author">
	<keyword>Markup</keyword>
	<keyword>ixml</keyword>
	<keyword>Invisible Markup</keyword>
	<keyword>notations</keyword>
	<keyword>parsing</keyword>
	<keyword>XML</keyword>
	<keyword>design</keyword>
	<keyword>XForms</keyword>
     </keywordset>
  </info>
  <section xml:id="L38">
    <title>Introduction</title>
    <para>
      The ixml language <citation>ixml</citation> was
      originally designed with the principal aim of allowing
      non-marked-up textual documents to be treated as if they were XML
      documents with markup. This can be seen as part of a progression
      of abstractions being made on documents:
    </para>
    <itemizedlist>
      <listitem>
        <para>
          originally there were individual (proprietary) documents,
          where each program that read them had to have have a special
          input routine for that format of data, with built-in knowledge
          of the underlying structure;
        </para>
      </listitem>
      <listitem>
        <para>
          introducing markup made the structure explicit, and enabled
          all data in all programs to be read by a single input routine;
        </para>
      </listitem>
      <listitem>
        <para>
          however, the marked-up data would often include markup to
          detail the presentation details; the introduction of style
          sheets added an abstraction layer that extracted the
          presentation into a separate file, which subsequently could be
          used for a whole class of similar documents;
        </para>
      </listitem>
      <listitem>
        <para>
          in the same way, ixml abstracts even the
          <emphasis>markup</emphasis> out of the documents into a
          separate file, similarly usable for a whole class of related
          documents.
        </para>
      </listitem>
    </itemizedlist>
    <para>
      The original design of ixml was not to convert textual documents
      to any <emphasis>particular</emphasis> XML document types, but
      just to get a textual document into an initial XML form that could
      later be refined as necessary using existing XML tools. So if you
      had an existing XML document type, it was unlikely to be
      producable with ixml directly, but only by producing an
      intermediate document type with ixml, and transforming that to the
      target document type with other tools.
    </para>
    <para>
      However it is possible to work in the other direction, that is to
      say, if you have an existing XML document type, that doesn't have
      a particular flat textual equivalent already, you can use ixml to
      design a textual representation for it. People often seem to
      prefer authoring flat textual documents, because they can see and
      understand the structure unaided, and find the need to add markup
      to make it readable for computers a distraction. An example of
      this is Markdown
      <citation>md</citation>, which is a
      flat version of (X)HTML. Indeed there is an example of ixml being
      used to process Markdown in exactly this way
      <citation>adv</citation>.
    </para>
    <para>
      In an earlier ixml paper on Modularisation
      <citation>m12n</citation>, there was a hint of such an
      approach for XForms <citation>xf</citation> which exists
      as an XML language with no equivalent textual form; in that paper
      it was used to demonstrate the application of modularisation on a
      large example. In this paper we take this further, and examine the
      processes you have to go through to design a flat textual
      notation, and the options you have, and techniques you can use,
      using XForms as the target language.
    </para>
  </section>
  <section xml:id="L50">
    <title>The Approach</title>
    <para>
      The most important, and distinguishing factor of designing a
      notation for an existing XML document type is that the structure
      has already been specified: there are no decisions to be made on
      that front. As pointed out in the earlier example of defining ixml
      for markdown, the top level ixml rules for Markdown
      <emphasis>must</emphasis> be <code>html</code>,
      <code>head</code>, and <code>body</code>, since they
      have to match the final target structure.
    </para>
    <para>
      Similarly in the case of XForms, the overall structure of the
      rules has already been decided for us, which we can determine
      directly from the XForms schema, thus giving at the top level the
      ixml rules:
    </para>
<programlisting xml:space="preserve">
         model: (instance; bind; action; submission)*.
      -Content: Controls.
     -Controls: Core-Controls; group; switch; repeat.
-Core-Controls: input; secret; textarea; output; upload; 
                range; trigger; submit; select; select1.
</programlisting>
    <para>
      (as in the XForms specification, all rule names with an initial
      lower-case letter are used for actual elements that will occur in
      the output, and names with an initial capital for other rules).
    </para>
    <para>
      Of course, XForms wasn't designed to be a standalone language, but
      one embedded in other languages, so we need to specify a top-level
      structure in a host language, in this case XHTML:
    </para>
<programlisting xml:space="preserve">
html: head, body.
</programlisting>
    <para>
      where <code>head</code> contains the models, and
      <code>body</code> contains the content. For instance:
    </para>
<programlisting xml:space="preserve">
head: title, Style*, model+.
body: Content.
</programlisting>
  </section>
  <section xml:id="L1501">
    <title>Recognising Input</title>
    <para>
      There are two approaches to recognising input: either by position,
      or by adding extra characters to identify what we are dealing
      with.
    </para>
    <para>
      For instance, since the title is the first item in the head, we
      can just use positioning and require that the first line be the
      title of our XForm:
    </para>
<programlisting xml:space="preserve">
title: ~[#a]+, nl.
</programlisting>
    <para>
      The rule for <code>nl</code> requires a newline, and allows
      extra optional trailing space:
    </para>
<programlisting xml:space="preserve">
-nl: -#a, s?.
</programlisting>
    <para>
      The rule for <code>s</code> is to allow trailing space, but
      we will also use it where spacing is required, not just optional:
    </para>
<programlisting xml:space="preserve">
-s: -[" "; #9; #a]+.
</programlisting>
    <para>
      For styling we use extra characters to identify the input, in this
      case the word "style". Although it would also be
      possible to allow embedded CSS, to keep it simple we will just use
      html <code>link</code> elements:
    </para>
<programlisting xml:space="preserve">
           Style: -"style", s, link.
            link: href, Style-type, Style-rel.
           @href: URL.
@Style-type&gt;type: +"text/css".
  @Style-rel&gt;rel: +"stylesheet".
            -URL: [L;"0"-"9"; ":/@.~#?"]+. {A simple version for now}
</programlisting>
    <para>
      This requires a URL, and adds two other attributes to the output.
      Note how ixml renaming has been used; although this is not yet
      officially part of ixml, it is in the evolving future
      specification <citation>ixml2</citation> and in all
      implementations. Also note the use of insertions to provide fixed
      content for some elements. So if a flat XForm begins:
    </para>
<programlisting xml:space="preserve">
XForm Example
style app.css
</programlisting>
    <para>
      we will get an output that starts:
    </para>
<programlisting xml:space="preserve">
&lt;html&gt;
   &lt;head&gt;
      &lt;title&gt;XForm Example&lt;/title&gt;
      &lt;link href='app.css' type='text/css' rel='stylesheet'/&gt;
</programlisting>
  </section>
  <section xml:id="L2231">
    <title>A Reminder About Spacing</title>
    <para>
      Although this has been treated elsewhere
      <citation>adv</citation>, it is worth pointing out the
      best technique for dealing with white space, since it is an easy
      source of ambiguity.
    </para>
    <para>
      The first tip is: consume extraneous spaces
      <emphasis>after</emphasis> recognising a symbol. For instance:
    </para>
<programlisting xml:space="preserve">
name: [L]+, s?.
</programlisting>
    <para>
      In that way, having recognised a <code>name</code>, the
      parser is positioned at the next meaningful (i.e., non-space)
      character, and doesn't have to try lots of different rules
      beginning with a space. It also means that extra whitespace at the
      end of the document is already dealt with.
    </para>
    <para>
      Secondly: recognise spaces as early as possible. Do this:
    </para>
<programlisting xml:space="preserve">
id: -"#", name.
-name: [L]+, s?.
</programlisting>
    <para>
      and not this:
    </para>
<programlisting xml:space="preserve">
id: -"#", name, s?.
-name: [L]+.
</programlisting>
    <para>
      and certainly never this:
    </para>
<programlisting xml:space="preserve">
id: -"#", name, s?.
-name: [L]+, s?.
</programlisting>
    <para>
      because in that case, if you had <code>#abc</code> followed
      by a space, the parser wouldn't know whether the space was a part
      of <code>id</code> or <code>name</code>, in other
      words, you would get an ambiguous parse.
    </para>
  </section>
  <section xml:id="L123">
    <title>Namespaces</title>
    <para>
      This brings us to the sticky question of namespaces; sticky,
      because at the time of writing, the issue is not yet resolved in
      the working group.
    </para>
    <para>
      The XML design group did a clever thing when designing a notation
      for namespaces <citation>xmlns</citation>: they designed
      the namespace declarations to look like attributes, so that XML
      documents would be syntactically compatible with earlier software.
      Thus although namespace declarations <emphasis>look</emphasis>
      like attributes, they have a different semantic interpretation
      because they begin with the characters <code>xmlns</code>.
    </para>
    <para>
      It is this author's opinion that since ixml is just producing an
      XML document, it can use the same approach, by specifying that
      things that look like attributes should be interpreted as
      namespace declarations if the serialisation of the node starts
      with the letters <code>xmlns</code>. For implementations
      that produce textual output, this adds no extra processing; for
      implementations that go directly to an XML internal form, the
      namespace declarations have to be recognised and handled
      appropriately.
    </para>
    <para>
      Accepting this, we can redefine the <code>html</code> rule
      to include a namespace in this way:
    </para>
<programlisting xml:space="preserve">
           html: xhtml-ns, head, body.
@xhtml-ns&gt;xmlns: +"http://www.w3.org/1999/xhtml".
</programlisting>
    <para>
      which will give:
    </para>
<programlisting xml:space="preserve">
&lt;html xmlns='http://www.w3.org/1999/xhtml'&gt;
</programlisting>
  </section>
  <section xml:id="L150">
    <title>Content</title>
    <para>
      We can use a similar approach to enclose the XForms controls in
      the body in an element that declares the namespace:
    </para>
<programlisting xml:space="preserve">
          body: Content.
 Content&gt;group: xf-ns, Controls.
  @xf-ns&gt;xmlns: +"http://www.w3.org/2002/xforms".
     -Controls: Control*.
      -Control: CoreControl; group; switch; repeat.
  -CoreControl: input; secret; textarea; output; upload;
                range; trigger; submit; select; select1.
</programlisting>
    <para>
      which will give:
    </para>
<programlisting xml:space="preserve">
&lt;body&gt;
   &lt;group xmlns='http://www.w3.org/2002/xforms'&gt;
</programlisting>
  </section>
  <section xml:id="L160">
    <title>Simple Controls</title>
    <para>
      Most controls have a number of required parameters, and a number
      of optional ones. For instance, consider <code>input:</code>
    </para>
<programlisting xml:space="preserve">
&lt;input ref="person/@age"&gt;
   &lt;label&gt;Age&lt;/label&gt;
&lt;/input&gt;
</programlisting>
    <para>
      We can define this using positioning after a leading keyword:
    </para>
<programlisting xml:space="preserve">
input person/@age "Age"
</programlisting>
    <para>
      like this:
    </para>
<programlisting xml:space="preserve">
input: -"input", s, ref, label.
 @ref: XPath.
label: -'"', ~['"'; #a]*, -'"', s?.
XPath: [L; "0"-"9"; "/:@[]()+-*'&gt;&lt;!=."]+, s?. {A simple version for now}
</programlisting>
    <para>
      There's one other useful attribute for several controls, and that
      is <code>incremental="true"</code> that specifies
      that the control activates for every character typed. Since
      <code>incremental="false"</code> is the default,
      we don't have to specify it, so you can write:
    </para>
<programlisting xml:space="preserve">
input person/@age "Age" incremental
</programlisting>
    <para>
      by changing the rule for <code>input</code> to:
    </para>
<programlisting xml:space="preserve">
       input: -"input", s, ref, label, incremental?.
@incremental: -"incremental", +"true", s?.
</programlisting>
    <para>
      so that we get:
    </para>
<programlisting xml:space="preserve">
&lt;input ref='person/@age' incremental='true'&gt;
   &lt;label&gt;Age&lt;/label&gt;
&lt;/input&gt;
</programlisting>
  </section>
  <section xml:id="L197">
    <title>Common Attributes</title>
    <para>
      Nearly all elements in XForms can have certain common attributes,
      in particular <code>class</code> for presentation purposes,
      and <code>id</code> for identification.
    </para>
<programlisting xml:space="preserve">
&lt;output class="error" id="out1" ref="message"&gt;
   &lt;label&gt;Error&lt;/label&gt;
&lt;/input&gt;
</programlisting>
    <para>
      One option would be to give these a keyword to identify them:
    </para>
<programlisting xml:space="preserve">
output class:error id:out1 message "Error"
</programlisting>
    <para>
      but another would be to use the same notation as used in CSS
      <citation>css</citation>:
    </para>
<programlisting xml:space="preserve">
output.error #out1 message "Error"
</programlisting>
    <para>
      like this:
    </para>
<programlisting xml:space="preserve">
output: -"output", class?, id?, ref, label.
@class: -".", name.
   @id: -"#", name.
 -name: [L], [L; "0"-"9"]+, s?.
</programlisting>
    <para>
      We can group them together as Common attributes:
    </para>
<programlisting xml:space="preserve">
-Common: class?, id?.
</programlisting>
    <para>
      and use them everywhere:
    </para>
<programlisting xml:space="preserve">
output: -"output", Common, ref, label.
</programlisting>
  </section>
  <section xml:id="L219">
    <title>The Model</title>
    <para>
      Going back to the definition of the head:
    </para>
<programlisting xml:space="preserve">
head: title, Style*, model+.
</programlisting>
    <para>
      we have to define the model. For instance:
    </para>
<programlisting xml:space="preserve">
         model: "model", s, id?, Model-content.
-Model-content: (instance; bind; Action; submission)*.
      instance: -"data", s, id?, src.
          @src: URL.
          bind: -"properties", s, ref, Property+.
     -Property: type; constraint; relevant; required; readonly.
         @type: -"type:", s?, name.
   @constraint: -"constraint:", s?, Expression.
   -Expression: XPath.
</programlisting>
    <para>
      (we'll come back to <code>Action</code> and
      <code>submission</code> later), looking like this:
    </para>
<programlisting xml:space="preserve">
model
   data people.xml
   properties person/@age type:integer constraint:.&gt;0
</programlisting>
    <para>
      As you can see, we are not obliged to use the same keywords in the
      input as the elements in the output, so in this case, for example, 
      we have replaced the somewhat technical-sounding
      <code>instance</code> with the more general
      <code>data</code>, and <code>bind</code> with
      <code>properties</code>.
    </para>
    <para>
      To distinguish the various types of property in a bind, we have to
      use keywords like this, however another approach would be to give
      them each a separate definition:
    </para>
<programlisting xml:space="preserve">
 -Model-content: (instance; Bind; Action; submission)*.
          -Bind: Type; Constraint; Relevant; Required; Readonly.
      Type&gt;bind: -"type", s, ref, s, type.
          @type: name.
Constraint&gt;bind: -"constraint", s, ref, constraint.
    @constraint: Expression.
</programlisting>
    <para>
      etc., giving:
    </para>
<programlisting xml:space="preserve">
model
   data people.xml
   type person/@age integer
   constraint person/@age .&gt;0
</programlisting>
    <para>
      yielding:
    </para>
<programlisting xml:space="preserve">
&lt;model&gt;
   &lt;instance src='people.xml'/&gt;
   &lt;bind ref='person/@age' type='integer'/&gt;
   &lt;bind ref='person/@age' constraint='.&gt;0'/&gt;
</programlisting>
    <para>
      It is worth noting that nearly all XForms applications only have a
      single model, so an alternative approach is to define models so
      that in the simple (usual) case you don't have to declare a model
      at all, only when there is more than one:
    </para>
<programlisting xml:space="preserve">
               head: title, Style*, Models.
            -Models: Single-model; model+.
-Single-model&gt;model: Model-content.
              model: -"model", s, id?, Model-content.
</programlisting>
    <para>
      allowing in the simple case:
    </para>
<programlisting xml:space="preserve">
XForms Example
style app.css
data people.xml
   type person/@age integer
   constraint person/@age .&gt;0
</programlisting>
  </section>
  <section xml:id="L257">
    <title>Container Controls</title>
    <para>
      Some controls can contain other content, and be nested, the
      simplest case being <code>group</code>:
    </para>
<programlisting xml:space="preserve">
&lt;group&gt;
   ...controls...
&lt;/group&gt;
</programlisting>
    <para>
      So we have a design a syntax for this style of control. Options
      could include:
    </para>
<programlisting xml:space="preserve">
group:
   ...
:group
</programlisting>
    <para>
      or
    </para>
<programlisting xml:space="preserve">
group
   ...
/group
</programlisting>
    <para>
      or
    </para>
<programlisting xml:space="preserve">
group{
   ...
}group
</programlisting>
    <para>
      or indeed
    </para>
<programlisting xml:space="preserve">
group {
   ...
}
</programlisting>
    <para>
      It is also worth noting that controls that are not in themselves
      principally containers, may nevertheless also contain content:
    </para>
<programlisting xml:space="preserve">
&lt;input ref="person/@age"&gt;
   &lt;label&gt;Age&lt;/label&gt;
   &lt;dispatch name="CHANGED" targetid="m" ev:event="xforms-value-changed"/&gt;
&lt;/input&gt;
</programlisting>
    <para>
      so it would be good if any syntax we choose be consistent with
      these cases. For instance:
    </para>
<programlisting xml:space="preserve">
input person/@age "Age" {
   dispatch CHANGED m xforms-value-changed
}
</programlisting>
    <para>
      and
    </para>
<programlisting xml:space="preserve">
input person/@age "Age" {
   hint "An integer"
}
</programlisting>
    <para>
      We can do this by declaring a block:
    </para>
<programlisting xml:space="preserve">
-Block: -"{", s?, Controls, "}", s?.
</programlisting>
    <para>
      and then define <code>group</code> as:
    </para>
<programlisting xml:space="preserve">
group: -"group", Common, ref?, label?, Block.
</programlisting>
    <para>
      which requires a block, and
    </para>
<programlisting xml:space="preserve">
input: -"input", Common, ref, label, incremental?, Block?
</programlisting>
    <para>
      where it is optional.
    </para>
    <para>
      For the <code>switch</code> control, it could look like
      this:
    </para>
<programlisting xml:space="preserve">
switch {
   case #closed
        trigger "&gt;" {
           toggle open DOMActivate
        }
   case #open
        trigger "&lt;" {
          toggle close DOMActivate
        }
        repeat item {
           output .
        }
}
</programlisting>
    <para>
      Defined like this:
    </para>
<programlisting xml:space="preserve">
switch: -"switch", Common, Cases.
-Cases: -"{", s?, case+, -"}", s?.
  case: id, Controls.
</programlisting>
  </section>
  <section xml:id="L405">
    <title>Actions</title>
    <para>
      XForms actions respond to asynchronous events that may occur. We
      have already seen a few above, such as <code>toggle</code>,
      and <code>dispatch</code>. These all have various
      attributes, plus optionally an event that they are responding to.
      For instance within a submission, a
      <code>setvalue</code> might look like this.
    </para>
<programlisting xml:space="preserve">
&lt;setvalue ref="message" ev:event="xforms-submit-error"&gt;Failed&lt;/setvalue&gt;
</programlisting>
<para>
   We could represent this directly as:
</para>
<programlisting xml:space="preserve">
setvalue message "Failed" xforms-submit-error
</programlisting>
    <para>
      However, <code>setvalue</code> can also calculate a value:
    </para>
<programlisting xml:space="preserve">
&lt;setvalue ref="count" value=".+1" ev:event="DOMActivate"/&gt;
</programlisting>
    <para>
      Luckily these two cases are syntactically distinguishable, so we
      can define it as:
    </para>
<programlisting xml:space="preserve">
         setvalue: -"setvalue", s, ref, (string; value), event.
           @value: expression.
@event&gt;"ev:event": name.
</programlisting>
    <para>
      There is a grouping element for several actions, called
      <code>action</code>:
    </para>
<programlisting xml:space="preserve">
&lt;action ev:event="xforms-ready"&gt;
   &lt;setvalue ref="date" value="local-dateTime()"/&gt;
   &lt;dispatch name="TICK" targetid="clock"/&gt;
&lt;/action&gt;
</programlisting>
    <para>
      We can treat that in the same way that we treated
      <code>group</code> earlier:
    </para>
<programlisting xml:space="preserve">
      action: -"action", s, event, ActionBlock.
-ActionBlock: -"{", s?, Action*, -"}", s?.
     -Action: toggle; setvalue; dispatch; action. {etc}
</programlisting>
    <para>
      allowing:
    </para>
<programlisting xml:space="preserve">
action xforms-ready {
   setvalue date local-dateTime()
   dispatch TICK clock
}
</programlisting>
    <para>
      However, we are not confined to doing it this way. Another
      approach would express it as:
    </para>
<programlisting xml:space="preserve">
xforms-ready? {
   setvalue date local-dateTime()
   dispatch TICK clock
}
</programlisting>
    <para>
      defined by:
    </para>
<programlisting xml:space="preserve">
action: event, -"?", s?, (Action; ActionBlock).
</programlisting>
    <para>
      which would also allow:
    </para>
<programlisting xml:space="preserve">
DOMActivate? setvalue count .+1
</programlisting>
  </section>
  <section xml:id="L297">
    <title>Submission</title>
    <para>
      The <code>submission</code> element is the most complex one
      in XForms for the simple reason that HTTP submission is
      complicated, and the element tries to cover all cases. Therefore
      we will only address a subset of its features here.
    </para>
    <para>
      A typical submission looks like this:
    </para>
<programlisting xml:space="preserve">
&lt;submission id="save" method="put" ref="instance('data')" 
            resource="data.xml" replace="none"&gt;
    &lt;setvalue ref="message" ev:event="xforms-submit-error"&gt;Save failed&lt;/setvalue&gt;
    &lt;setvalue ref="message" ev:event="xforms-submit-done"/&gt;
&lt;/submission&gt;
</programlisting>
    <para>
      which could be represented like this:
    </para>
<programlisting xml:space="preserve">
submission #save put instance('data') data.xml replace:none {
   xforms-submit-error? setvalue message "Save failed" 
   xforms-submit-done? setvalue message ""
}
</programlisting>
    <para>
      However, this is such a common pattern, it might be worth
      enforcing the handling of the return events, something like this:
    </para>
<programlisting xml:space="preserve">
submission #save put:instance('data') to:data.xml replace:none {
   FAILURE setvalue message "Save failed"
   SUCCESS setvalue message ""
}
</programlisting>
    <para>
      along these lines:
    </para>
<programlisting xml:space="preserve">
        submission: -"submission", Common, s, Method, resource, replace?, SubBlock.
           -Method: PUT; GET; POST; DELETE; HEAD.
              -PUT: method-put, ref.
              -GET: method-get, ref.
@method-put&gt;method: -"put:", +"PUT".
@method-get&gt;method: -"get:", +"GET".
</programlisting>
    <para>
      etc., and then define a Submission Block to allow the success and
      failure parts in either order:
    </para>
<programlisting xml:space="preserve">
            -SubBlock: -"{", s?, (SUCCESS, FAILURE; FAILURE, SUCCESS), -"}", s?.
       SUCCESS&gt;action: -"SUCCESS", s?, evSuccess, (Action; ActionBlock).
@evSuccess&gt;"ev:event": +"xforms-submit-done".
       FAILURE&gt;action: -"FAILURE", s?, evFailure, (Action; ActionBlock).
@evFailure&gt;"ev:event": +"xforms-submit-error".
</programlisting>
    <para>
      giving an output like this:
    </para>
<programlisting xml:space="preserve">
&lt;submission id='save' method='PUT' ref='instance(&amp;apos;data&amp;apos;)' resource='data.xml' replace='none'&gt;
   &lt;action ev:event='xforms-submit-error'&gt;
      &lt;setvalue ref='message'&gt;Save failed&lt;/setvalue&gt;
   &lt;/action&gt;
   &lt;action ev:event='xforms-submit-done'&gt;
      &lt;setvalue ref='message'/&gt;
   &lt;/action&gt;
&lt;/submission&gt;
</programlisting>
  </section>
  <section xml:id="L293">
    <title>Embedded XML</title>
    <para>
      Although we can easily embed and recognise other languages such as
      CSS in our flat XForms, there is an irony that we can't embed raw
      XML. This is partly because we can't get the names of the elements
      into the output form (though see
      <citation>gixml</citation> for an approach), and partly
      because serialising "&lt;" and "&gt;"
      characters would appear as "&amp;lt;" and
      "&amp;gt;", even if all we did was copy the embedded XML
      from input to output.
    </para>
  </section>
  <section xml:id="L301">
    <title>Conclusion</title>
    <para>
      This paper gives a taste of the option open to a format designer
      wanting to use ixml. What we have presented is not a complete or
      final design of a flat version of XForms, and there are still many
      details that need to be completed. For instance, it would be
      advantageous for the user if the structure of XPath is fully
      defined, so that syntax errors on XPath expressions are identified
      as early as possible.
    </para>
    <para>
      Designing a text notation for a given XML Document type is an
      interesting, even fun, exercise. While the overall structure of
      the document is already established, the designer has a lot of
      freedom in using keywords, extra characters, or positioning, to
      identify syntactic forms. While at first unexpected, there is also
      a lot of freedom in the choice of keywords and similar, that are
      not required to match the terminology used in the document type.
    </para>
  </section>
    <bibliography>
   <title>References</title>
   <bibliomixed xml:id="adv" xreflabel="Advanced Tutorial">Steven Pemberton, 
      <emphasis role="ital">Advanced Invisible XML (ixml) Tutorial</emphasis>, CWI, 2025, 
      <link xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">https://cwi.nl/~steven/ixml/advanced/</link>
   </bibliomixed>
   <bibliomixed xml:id="css" xreflabel="CSS">Håkon Wium Lie et al. (eds.), 
      <emphasis role="ital">Cascading Style Sheets level 1</emphasis>, W3C, 1996, 
      <link xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">https://www.w3.org/TR/CSS1/</link>
   </bibliomixed>
   <bibliomixed xml:id="gixml" xreflabel="Generalised ixml">Steven Pemberton, 
      <quote>Generalised Invisible Markup</quote>, <emphasis role="ital">Proc. Declarative Amsterdam</emphasis>, 2025, 
      <link xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">https://declarative.amsterdam/article?doi=da.2025.pemberton.generalised-invisible-markup</link>
   </bibliomixed>
   <bibliomixed xml:id="ixml" xreflabel="ixml">Steven Pemberton (ed.), 
      <emphasis role="ital">Invisible XML Specification</emphasis>, Invisible XML Organisation, 2022, 
      <link xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">https://invisiblexml.org/1.0/</link>
   </bibliomixed>
   <bibliomixed xml:id="ixml2" xreflabel="Draft ixml">Steven Pemberton (ed.), 
      <emphasis role="ital">Invisible XML Specification Community Group Editorial Draft</emphasis>, Invisible XML Organisation, 2026, 
      <link xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">https://invisiblexml.org/current/</link>
   </bibliomixed>
   <bibliomixed xml:id="m12n" xreflabel="Modularised ixml">Steven Pemberton, 
      <quote>Modular ixml</quote>, <emphasis role="ital">Proc. MarkupUK 2025</emphasis>, pp 6-20, 
      <link xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">https://markupuk.org/pdf/proceedings-2025-2.pdf</link>
   </bibliomixed>
   <bibliomixed xml:id="md" xreflabel="Markdown">John Gruber, 
      <emphasis role="ital">Markdown</emphasis>, Daring Fireball, 2004, 
      <link xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">https://daringfireball.net/projects/markdown/</link>
   </bibliomixed>
   <bibliomixed xml:id="xf" xreflabel="XForms">Erik Bruchez et al. (eds.), 
      <emphasis role="ital">XForms 2.0</emphasis>, W3C, 2026, 
      <link xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">https://www.w3.org/community/xformsusers/wiki/XForms_2.0</link>
   </bibliomixed>
   <bibliomixed xml:id="xmlns" xreflabel="Namespaces">Tim Bray et al., 
      <emphasis role="ital">Namespaces in XML 1.0</emphasis>, W3C, 2009, 
      <link xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">https://www.w3.org/TR/xml-names/</link>
   </bibliomixed>
</bibliography>
</article>