Validación con XML Schema

Motivación

editar

Se desea utilizar una librería de XML Schema con restricciones para validar un Form.

Ejemplo funcional sample.xhtml

editar
<?xml version="1.0" encoding="UTF-8"?>
<html 
   xmlns="http://www.w3.org/1999/xhtml" 
   xmlns:xf="http://www.w3.org/2002/xforms" 
   xmlns:xs="http://www.w3.org/2001/XMLSchema" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:ftype="http://www.example.com/my-file-types">
   <head>
      <title>Validate Postal Codes</title>
      <style type="text/css">
         @namespace xf url("http://www.w3.org/2002/xforms");
         xf|input {
            display: table-row;
            line-height: 2em;
         }
         
         xf|label {
            display: table-cell;
            text-align: right;
            font-family: Arial, Helvetica, sans-serif;;
            font-weight: bold;
            padding-right: 5px;
            width: 150px;
         }
         
         *:required {
             background-color: yellow;
         }
         
         *:invalid  {
            background-color: pink;
         }
      </style>
      <xf:model schema="schema.xsd">
         <xf:instance src="instance.xml" />
         <xf:bind id="zip" required="true()" type="ftype:zipType" nodeset="ftype:zip" />
         <xf:bind id="zip2" required="true()" type="ftype:zip2Type" nodeset="ftype:zip2" />
      </xf:model>
   </head>
   <body>
      <xf:input bind="zip" incremental="true">
         <xf:label>Zip Code: </xf:label>
         <xf:hint>Validation is not correctly specified for this field</xf:hint>
         <xf:alert>The 'Zip Code' failed to validate!</xf:alert>
      </xf:input>
      <xf:input bind="zip2" incremental="true">
         <xf:label>Zip Code 2: </xf:label>
         <xf:hint>Validation is correctly specified for this field</xf:hint>
         <xf:alert>
           <xf:output value="concat('The &amp;quot;', name(), '&amp;quot; failed to validate!')" />
         </xf:alert>
      </xf:input>
   </body>
</html>

Ejemplo de un archivo XML Schema schema.xsd

editar
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 xmlns:ftype="http://www.example.com/my-file-types"
 targetNamespace="http://www.example.com/my-file-types"
 elementFormDefault="qualified" attributeFormDefault="unqualified">
   <xs:element name="data">
      <xs:annotation>
         <xs:documentation>Test XML Schema</xs:documentation>
      </xs:annotation>
      <xs:complexType>
         <xs:sequence>
            <xs:element name="zip" type="ftype:zipType"/>
         </xs:sequence>
      </xs:complexType>
   </xs:element>
   <xs:simpleType name="zipType">
      <xs:restriction base="xs:string">
         <!-- bad pattern: matches any sequence of 5 digits, even if there are more digits or non-numeric. -->
         <xs:pattern value="\d{5}"/>
      </xs:restriction>
   </xs:simpleType>
   <xs:simpleType name="zip2Type">
      <xs:restriction base="xs:string">
         <!-- good pattern: matches only 5 digits, nothing extra -->
         <xs:pattern value="^\d{5}$"/>
      </xs:restriction>
   </xs:simpleType>
</xs:schema>

Sample instance document instance.xml

editar
<?xml version="1.0" encoding="UTF-8"?>
<data xmlns="http://www.example.com/my-file-types">
  <zip>12345</zip>
  <zip2>12345</zip2>
</data>

Example XML Schema File schema.xsd

editar
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 xmlns:ftype="http://www.example.com/my-file-types"
 targetNamespace="http://www.example.com/my-file-types"
 elementFormDefault="qualified" attributeFormDefault="unqualified">
   <xs:element name="data">
      <xs:annotation>
         <xs:documentation>Test XML Schema</xs:documentation>
      </xs:annotation>
      <xs:complexType>
         <xs:sequence>
            <xs:element name="zip" type="ftype:zipType"/>
         </xs:sequence>
      </xs:complexType>
   </xs:element>
   <xs:simpleType name="zipType">
      <xs:restriction base="xs:string">
         <!-- bad pattern: matches any sequence of 5 digits, even if there are more digits or non-numeric. -->
         <xs:pattern value="\d{5}"/>
      </xs:restriction>
   </xs:simpleType>
   <xs:simpleType name="zip2Type">
      <xs:restriction base="xs:string">
         <!-- good pattern: matches only 5 digits, nothing extra -->
         <xs:pattern value="^\d{5}$"/>
      </xs:restriction>
   </xs:simpleType>
</xs:schema>

Ejemplo de un documento instanciado instance.xml

editar
<?xml version="1.0" encoding="UTF-8"?>
<data xmlns="http://www.example.com/my-file-types">
  <zip>12345</zip>
  <zip2>12345</zip2>
</data>