2 Introduction au langage XForms

La conception du langage XForms est le fruit d'une expérience de plusieurs années avec les formulaires HTML. Ceux-ci ont formé l'ossature de la révolution du commerce électronique et, ayant prouvé leur valeur, ont aussi montré les nombreuses façons dont ils pouvaient être améliorés.

La différence principale, lors d'une comparaison entre les formulaires XForms et HTML, hormis le fait que XForms soit dans le langage XML, c'est la séparation entre les données collectées et le balisage des commandes collectant les valeurs individuelles. Cette approche rend non seulement les formulaires XForms plus faciles à gérer, en définissant clairement ce qui est soumis et vers où cela l'est, mais aussi encourage la réutilisation des formulaires, puisque la partie essentielle sous-jacente d'un formulaire n'est plus irrémédiablement liée à la page qui l'utilise.

Une deuxième différence importante : le langage XForms, bien que conçu pour s'intégrer à XHTML, n'est plus restreint à être un sous-ensemble de ce langage et peut s'intégrer à n'importe quel langage de balisage compatible.

Le langage XForms s'est efforcé d'améliorer la création, la réutilisation, l'internationalisation, l'accessibilité, l'utilisabilité et l'indépendance par rapport au matériel. Voici un résumé des avantages principaux à l'utilisation de XForms :

Le typage fort

Les données soumises sont fortement typées et elles peuvent être vérifiées au moyen d'outils intégrés. Le remplissage d'un formulaire s'en trouve accéléré, dans la mesure où la nécessité des allers-retours au serveur pour validation est réduite d'autant.

La soumission XML

Elle pare à la nécessité d'une logique personnalisée côté serveur afin de rassembler les données soumises pour les passer à l'environnement d'application. L'environnement d'application peut directement valider et traiter le document d'instance XML reçu.

La réutilisation des schémas existants

Elle empêche la duplication et assure que la mise à jour des règles de validation, suite à un changement dans la logique commerciale sous-jacente, ne nécessite pas la redéfinition des contraintes de validation au sein de l'application XForms.

L'augmentation des schémas externes

Elle permet à l'auteur XForms de dépasser l'ensemble des contraintes de base issu de l'environnement. La définition d'autres contraintes dans le modèle XForms est susceptible d'améliorer l'utisabilité d'ensemble de l'application Web finale.

L'internationalisation

L'utilisation de XML 1.0, pour les données d'instance, assure que les données soumises sont prêtes pour une éventuelle internationalisation.

L'accessibilité améliorée

XForms sépare le contenu et la présentation. Les commandes de l'interface d'utilisateur encapsulent toutes les métadonnées pertinentes comme les étiquettes, améliorant ainsi l'accessibilité de l'application dans l'utilisation de modalités différentes. Les commandes de l'interface d'utilisateur XForms sont génériques et sont conçues pour être indépendantes par rapport au matériel.

La gestion d'appareils multiples

Le haut niveau d'abstraction des commandes de l'interface d'utilisateur et la définition orientée besoin de l'interface d'utilisateur qui en découle permettent de recibler cette interface vers des appareils différents.

L'utilisation moindre des scripts

En définissant des gestionnaires d'événement déclaratifs, basés sur XML, qui recouvrent les cas d'utilisation courants, on peut analyser de manière statique la majorité des documents XForms, réduisant les besoins de scripts impératifs pour les gestionnaires d'événements.

2.1 Un exemple

Selon l'approche XForms, les formulaires se composent d'une section qui décrit ce que fait le formulaire, qu'on appelle le modèle XForms, et d'une autre qui décrit comment le formulaire doit être présenté.

Prenons un formulaire de commerce électronique simple qui pourrait être restitué comme suit :

Cliché d'une restitution graphique

Clairement, la collecte concerne une valeur représentant le moyen de paiement employé, espèces ou carte de crédit, et s'il s'agit d'une carte de crédit, son numéro et sa date d'expiration.

On peut représenter cette collecte dans un élément XForms model, lequel, dans XHTML, serait typiquement contenu dans la section head :

<xforms:model>
  <xforms:instance>
    <ecommerce xmlns="">
      <methode/>
      <numero/>
      <expiration/>
    </ecommerce>
  </xforms:instance>
  <xforms:submission action="http://example.com/soumettre"
     method="post" id="soumission" includenamespaceprefixes=""/>
</xforms:model>

Cette déclaration annonce simplement que l'on collecte trois bouts d'information (remarquez que rien n'est dit, pour l'instant, à propos de leurs types), lesquels seront soumis en utilisant l'adresse URL de l'attribut action.

XForms 1.0 définit un ensemble de commandes de formulaire, neutre vis-à-vis des appareils et indépendant de la plateforme, qui convient pour une utilisation générale. Les commandes sont liées au modèle XForms via le mécanisme de liaison XForms, dans ce cas simple, au moyen de l'attribut ref sur les commandes. En XHTML, ce balisage apparaîtrait normalement dans la section body (remarquez que le préfixe d'espace de nommage XForms est ici intentionnellement déclaré implicite) :

<select1 ref="methode">
  <label>Choix mode de paiement :</label>
  <item>
    <label>Espèces</label>
    <value>espèces</value>
  </item>
  <item>
    <label>Crédit</label>
    <value>crédit</value>
  </item>
</select1>
<input ref="numero">
  <label>Numéro carte de crédit :</label>
</input>
<input ref="expiration">
  <label>Date d'expiration :</label>
</input>
<submit submission="soumission">
  <label>Envoyer</label>
</submit>

Notez que cette conception présente les caractéristiques suivantes :

Le fait de pouvoir relier des commandes de formulaire au modèle de cette manière simplifie l'intégration de XForms à d'autres langages hôtes, car on peut utiliser n'importe quel balisage de commande de formulaire pour la liaison au modèle.

2.2 La fourniture des données d'instance XML

Le processeur XForms peut directement soumettre les données collectées sous forme XML. Dans l'exemple, les données soumises auraient cet aspect :

Exemple : Les données soumises
<ecommerce>
  <methode>cc</methode>
  <numero>1235467789012345</numero>
  <expiration>2001-08</expiration>
</ecommerce>

Le traitement XForms assure le suivi de l'état du formulaire partiellement rempli au travers des ces données d'instance. Les valeurs initiales des données d'instance peuvent être fournies ou laissées vides comme dans l'exemple. L'élément instance contient essentiellement un squelette de document XML qui est mis à jour au fur et à mesure que l'utilisateur remplit le formulaire. Il donne à l'auteur le contrôle total de la structure des données XML soumises, y compris l'information d'espace de nommage. Lors de la soumission du formulaire, les données d'instance sont sérialisées comme document XML. Voici une autre version de l'exemple précédent :

Exemple : Le modèle
<xforms:model>
  <xforms:instance>
    <paiement methode="cc" xmlns="http://commerce.example.com/paiement">
      <numero/>
      <expiration/>
    </paiement>
  </xforms:instance>
  <xforms:submission action="http://example.com/soumettre"
     method="post" includenamespaceprefixes="#default"/>
</xforms:model>

Auquel cas, les données soumises auraient cet aspect :

Exemple : Les données soumises
<paiement methode="cc" xmlns="http://commerce.example.com/paiement">
  <numero>1235467789012345</numero>
  <expiration>2001-08</expiration>
</paiement>

Ce modèle possède des caractéristiques dignes d'être soulignées :

Pour relier ces données d'instance aux commandes de formulaire, il faut changer les attributs ref des commandes de formulaire, afin qu'ils pointent vers la partie convenable des données d'instance, en utilisant des expressions de liaison :

Exemple : Lier des commandes de formulaire à des nœuds d'instance avec l'attribut ref
... xmlns:my="http://commerce.example.com/paiement"
  ...
  <xforms:select1 ref="@methode">...</xforms:select1>
  ...
  <xforms:input ref="my:numero">...</xforms:input>
  ...
  <xforms:input ref="/my:paiement/my:expiration">...</xforms:input>

Les expressions de liaison se fondent sur le langage XPath [XPath 1.0], y compris l'emploi du caractère arobase @ pour appeler des attributs, comme c'est le cas ici. Remarquez que, pour les besoins de l'illustration, les deux premières expression utilisent le nœud de contexte XPath, lequel indique implicitement l'élément de niveau supérieur (ici l'élément my:paiement). La troisième expression montre un chemin absolu.

2.3 La contrainte des valeurs

XForms permet la validation des données au fur et à mesure du remplissage du formulaire. En l'absence d'information spécifique concernant les types des valeurs collectées, toutes les valeurs sont renvoyées en tant que chaînes, mais il est possible d'assigner des types aux valeurs dans les données d'instance. Dans cet exemple, l'élément numero ne devrait accepter que des chiffres et avoir entre 14 et 18 chiffres, et l'élément expiration ne devrait accepter que des combinaisons mois/date valides.

En outre, les commandes de formulaires numero et expiration, renseignant sur la carte de crédit, ne sont pertinentes que pour le choix "cc" de l'attribut methode, et elles sont obligatoires dans ce cas.

En définissant un composant supplémentaire, des propriétés d'élément de modèle, les auteurs peuvent inclure des informations de validation déclaratives riches dans les formulaires. Ces informations peuvent provenir de schémas XML tout comme d'ajouts propres à XForms, ainsi l'élément relevant. Ces propriétés apparaissent sur les éléments bind, tandis que les contraintes de schéma s'expriment dans un fragment de schéma XML direct ou bien externe. Par exemple :

Exemple : Validation déclarative avec des propriétés d'élément de modèle
... xmlns:my="http://commerce.example.com/paiement"...
        
  <xforms:model>
    ...
    <xforms:bind nodeset="/my:paiement/my:numero"
                 relevant="/my:paiement/@methode = 'cc'"
                 required="true()"
                 type="my:numerocc"/>
    <xforms:bind nodeset="/my:paiement/my:expiration"
                 relevant="/my:paiement/@methode = 'cc'"
                 required="true()"
                 type="xsd:gYearMonth"/>
    <xsd:schema ...>
      ...
      <xsd:simpleType name="numerocc">
        <xsd:restriction base="xsd:string">
          <xsd:pattern value="\d{14,18}"/>
        </xsd:restriction>
      </xsd:simpleType>
      ...
    </xsd:schema>
  </xforms:model>

Remarque :

Dans l'exemple précédent, l'expression de l'attribut relevant utilise une notation XPath absolue (commençant par /) parce que les nœuds du contexte d'évaluation des expressions calculées sont déterminés par l'expression de liaison de l'attribut ref de l'élément bind (cf. le chapitre 7.4 Le contexte d'évaluation), et ainsi tout chemin de nœud relatif dans l'attribut relevant du premier élément bind ci-dessus serait relatif à /my:paiement/my:numero.

2.4 Des documents avec plusieurs formulaires

Le traitement XForms ne fixe aucune limite au nombre de formulaires qui peuvent être placés dans un seul document conteneur. Lorsqu'un seul document contient plusieurs formulaires, chaque formulaire utilisera un élément model avec un attribut id, de sorte qu'on puisse les appeler depuis ailleurs dans le document conteneur.

En outre, les commandes de formulaire devraient indiquer quel élément model contient les données d'instance auxquelles elles se lient. On réalise cette opération au travers d'un attribut model appartenant à la catégorie des attributs de liaison. Si aucun attribut model n'est indiqué sur l'élément de liaison, on utilisera l'attribut model de l'élément de liaison ancêtre le plus proche, et sinon, le premier modèle XForms dans l'ordre du document. Cette technique, appelée résolution dans la visibilité, est fréquemment employée dans XForms.

L'exemple suivant ajoute un sondage d'opinion à notre formulaire de commerce électronique ;

Exemple : Ajouter le modèle opinion
<xforms:model>
  <xforms:instance>
    ...données d'instance de paiement...
  </xforms:instance>
  <xforms:submission action="http://example.com/soumettre" method="post"/>
</xforms:model>
        
<xforms:model id="opinion">
  <xforms:instance>
    <utilite/>
  </xforms:instance>
  <xforms:submission id="soumettreopinion" .../>
</xforms:model>

En outre, le balisage suivant apparaîtrait dans la section du corps du document :

Exemple : Commandes de formulaire du modèle opinion
<xforms:select1 ref="/utilite" model="opinion">
  <xforms:label>Avez-vous trouvé cette page utile ?</xforms:label>
  <xforms:item>
    <xforms:label>Pas du tout utile</xforms:label>
    <xforms:value>0</xforms:value>
  </xforms:item>
  <xforms:item>
    <xforms:label>Peu utile</xforms:label>
    <xforms:value>1</xforms:value>
  </xforms:item>
  <xforms:item>
    <xforms:label>Utile en quelque sorte</xforms:label>
    <xforms:value>2</xforms:value>
  </xforms:item>
  <xforms:item>
    <xforms:label>Très utile</xforms:label>
    <xforms:value>3</xforms:value>
  </xforms:item>
</xforms:select1>
        
<xforms:submit submission="soumettreopinion">
  <xforms:label>Envoyer</xforms:label>
</xforms:submit>

La différence principale ici c'est l'emploi de l'attribut model="opinion" pour identifier l'instance. Remarquez que l'élément submit se rapporte à l'élément submission par un ID et ne nécessite pas d'attribut de liaison.

On trouvera des exemples XForms plus complexes dans G Exemples XForms complets.