XML Schema < part 3 >

Posted by Brunda on Thu, 23 Dec 2021 17:27:44 +0100

There are two ways to verify whether an XML document conforms to the agreed XML structure: DTD schema and XML Schema. This article mainly introduces XML Schema.

1, Advantages of XML Schema

  1. XML Schema is based on XML and has no special syntax.
  2. XML Schema can be parsed and processed like other XML files.
  3. XML Schema supports a series of data types (int, float, Boolean, date, etc.).
  4. XML Schema provides an extensible data model.
  5. XML Schema supports comprehensive namespaces.
  6. XML Schema supports attribute groups.

2, XSD

XSD documents must contain at least: schema root element, XML schema namespace definition and element definition. It should be noted that one and only one schema root element must be defined in XSD. The root element includes schema constraints, XML schema namespace definitions, other namespace definitions, version information, language information and other information.

1. schema root element

The syntax is as follows:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  ...
</xsd:schema>

2. Element

The syntax is as follows:

<xsd:element name="user" type="xsd:string" />

Elements in XSD are declared using element identifiers. In the above example, the name attribute is the name of the element and the type attribute is the type of element value, which can make the data type or other types built-in in XML Schema.

All elements are as follows:

element

explain

name

Name of the element

type

Type of element value

minOccurs

The minimum number of occurrences of the element in the parent element (the default is 1, which must be greater than or equal to 0)

maxOccurs

The maximum number of occurrences of this element in the parent element (the default is 1, which must be greater than or equal to 0). When it is set to unbounded, it means there is no limit.

3. Reference element

The reference element is implemented using the ref attribute of the element flag. It is mainly used to avoid defining the same element multiple times in the document. Indicates that the current element is the same as the referenced element.

The syntax is as follows:

<xsd:element name="user" type="xsd:string" />
<xsd:sequence>
    <xsd:element ref="user" />  <!--The current element is user element-->
</xsd:sequence>

4. Alias

The alias is mainly implemented by using the attribute substitutionGroup in the element identifier.

Syntax:

<xsd:element name="user" type="xsd:string" substitutionGroup="yonghu" />

This statement indicates that the element name of this line can be user or user, such as:

<yonghu>admin</yonghu>
<user>admin</user>

Both lines of xml are qualified.

5. Set default and fixed values

The syntax is as follows:

<xsd:element name="city" type="xsd:string" default="xian" />
<xsd:element name="country" type="xsd:string" fixed="china" />

By setting the default attribute, you can assign a default value when the city is not defined in the XML document, but use the fixed attribute to set a fixed value china for the element country, and it is not allowed to change.

6. Using combiner control structure

1. sequence combiner, which defines that a list of elements must be displayed in the order specified in the schema (or not if it is optional).

<xsd:sequence>
  <xsd:element name="first" type="xsd:string" />
  <xsd:element name="middle" type="xsd:string" />
  <xsd:element name="last" type="xsd:string" />        
</xsd:sequence>

2. The all combiner allows the defined elements to be displayed in any order. The child elements of the all element are required by default and can be displayed at most once at a time.

<xsd:all minOccurs="0">
  <xsd:element name="first" type="xsd:string" />
  <xsd:element name="middle" type="xsd:string" />
  <xsd:element name="last" type="xsd:string" />        
</xsd:all>

(3)choice combiner, which allows you to specify one of multiple groups of declarations for mutual exclusion.

<xsd:choice>
  <xsd:element name="first" type="xsd:string" />
  <xsd:element name="middle" type="xsd:string" />
  <xsd:element name="last" type="xsd:string" />        
</xsd:choice>

7. Define properties

In XML Schema documents, attributes can be defined according to the method of defining elements, but they are highly restricted. The attributes that can be applied to the attribute element definition are shown in the following table.

attribute

meaning

defalt

Initial default

fixed

Fixed attribute values that cannot be modified and overwritten

name

The name of the property

ref

A reference to the previous property definition

type

XSD type or simple type of the attribute

use

How to use the attribute optional (i.e. the attribute is not required, but this is the default), prohibited (prohibited) or required (mandatory).

form

Determine the local address of attributeFormDefault

id

Unique ID of the attribute in the schema document

8. Create attribute

The syntax is as follows:

<xsd:attribute name="age" type="xsd:integer" />

This statement defines an attribute called age, whose value must be an integer. When it is added to a schema, it must be a child of a schema element, a complexType element, or an attributeGroup element.

Code example:

<xsd:element name="name">
  <xsd:complexType>
    <xsd:sequence>
      <xsd:element name="first" type="xsd:string" />
    </xsd:sequence>
    <xsd:attribute name="age" type="xsd:integer" use="optional" />   <!--Add attribute to element name Attribute-->  
  </xsd:complexType>
</xsd:element>

The valid XML documents corresponding to the above documents are as follows:

<?xml version="1.0"?>
<name age="27">
  <first>string</first>
</name>

This example not only illustrates the following constraint properties, but also shows the usage of compositor.

3, XML Schema data type

1. Schema basic data type

The basic data types of Schema are as follows:

data type

explain

boolean

true/false

datetime

Format: ccyy mm ddthh: mm: SS

decimal

Decimal digits of arbitrary precision

string

String data

int

integer

nonNegativeInteger

Integer greater than or equal to 0

nonPositiveInteger

Integer less than or equal to 0

short

Short integers - 32768 to 32767

2. Constraints

Although the built-in data type function has certain restrictions, it is still far from enough. For further constraints, let's take a look at the constraints.

constraint

explain

enumeration

A set of specified values separated by spaces that constrains the data type to the specified value

fractionDigit

Specifies the maximum number of digits after the decimal point

length

Length unit

minExclusive

Lower limit value

maxExclusive

Upper limit value

minLength

Minimum length unit

maxLength

Maximum length unit

minInclusive

Minimum value. All values should be greater than or equal to this value

maxInclusive

Maximum value, all values should be less than or equal to this value

pattern

The value of the data type must match the specified pattern and must be a regular expression

totalDigits

Specifies the value for the maximum number of decimal places

whiteSpace

The values are preserve (the spaces in the value cannot be changed), replace (all tabs, line breaks and carriage returns are replaced by spaces), and collapse (execute replace to delete the adjacent spaces at the end and beginning).

To use the constraints of the above constraint table, you need to use the element restriction. There are two attributes in this element: the ID attribute is the location identifier of the restriction element in the schema document; The base attribute is set to a built-in XSD data type or an existing simple type definition, which is a restricted type.

Example: set the value range of an integer between 1 and 100.

<xsd:restriction base="xsd:int">
  <xsd:minInclusive value="1" />
  <xsd:maxInclusive value="100" />
</xsd:restriction>

3. Simple type

A simple type is a custom data type that further limits the possible values of a node. To create a simple type, you need to use the simpleType element, which is defined as follows:

<simpleType id="ID" name="NCName" final="(#all|((list|union|restriction)))" />

The ID attribute should uniquely identify the simpleType element in the document, and the name cannot use colon characters. simpleType cannot contain elements or attributes. It is basically a value or a collection of values.

For example:

<xsd:simpleType name="USState">
  <xsd:restriction base="xsd:string">
    <xsd:enumeration value="AK">
    <xsd:enumeration value="AL">
    <xsd:enumeration value="AR">
  </xsd:restriction>
</xsd:simpleType>
<xsd:element name="statement" type="USState" />

The valid xml documents corresponding to the above documents are as follows:

<statement>AK</statement>  

Note that the value can only be one of AK, AR and AL.

4. List type

List can be used to define list types.

<xsd:simpleType name="listOfIntType">
  <xsd:list itemType="Integer"/>
</xsd:simpleType>
<xsd:element name="listOfMyInt" type="listOfType"/>

listIfIntType is defined as a list of integets. The value of the element listOfMyInt can be several integers separated by spaces.

Valid xml documents are as follows:

<listOfMyInt>1 2 3 123</listOfMyInt>

5. Joint type

Union can be used to define a union type. For example:

<xsd:simpleType name="zipUnion">
  <xsd:union memberTypes="USState listOfMyIntType"/>
</xsd:simpleType>
<xsd:element name="zips" type="zipUnion"/>

Union is used to define a union type. The member types include USState and listOfMyIntType. The value of the element to which the union type is applied can be an example of one of these atomic types or list types, but an element instance cannot contain two types at the same time.

Valid XML documents are as follows:

<zips>CA</zips>
<zips>9192 192391 129</zips>
<zips>AK</zips>

Invalid XML document is as follows:

<zips>AL 2231</zips>

It is wrong to include two at the same time.

6. Anonymous type

When defining an element type, you always define a data type first, and then set the element type to the newly defined data type. If the new data type is used only once, we can set it directly in the element definition without other external settings.

For example:

  <xsd:element name="quantity">
    <xsd:simpleType>
      <xsd:restriction base="xsd:positiveInteger">
          <xsd:maxExclusive value="100"/>
      </xsd:restriction>
    </xsd:simpleType>
  </xsd:element>

The type of element quantity is an integer from 1 to 99. This type, which is not introduced by type and is directly defined in the element element, is called anonymous type.

7. Complex type

The definition of a complex type must use the complexType element, which can contain attributes and elements. In the use of complex types, complexType and simpleType are mainly used together.

8. Content model

The content model can limit the elements, attributes and types used in XML documents, and determine which levels of XML instances users can add their own elements and attributes.

1. any content model

When declaring elements in XML, any is the default content model, which can contain text, elements, and spaces.

For example:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="name">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="first" type="xsd:string" />
        <xsd:element name="middle" type="OtherNames" />
        <xsd:element name="last" type="xsd:string" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
  <xsd:complexType name="OtherNames">
    <xsd:sequence>
      <xsd:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
    </xsd:sequence>
  </xsd:complexType>
</xsd:schema>

In the example, the xsd:any element indicates that the type allows adding content.

The allowed values for the namespace property are:

  1. ##Any: the element can come from any namespace.
  2. ##Other: an element can come from a namespace other than the target namespace where the parent element of the element is located.
  3. ##local: element is not restricted by namespace.
  4. ##targetNamespace: the element comes from the target namespace of the parent element.

The processContents attribute describes the action to be taken when validating the element created here.

The processContents attribute has the following three values:

  1. strict: indicates which namespaces the XML processor must obtain the schema associated with and validate elements and attributes.
  2. lax: similar to strict, but if the processor cannot find the schema document, there will be no error.
  3. skip: do not validate XML documents with schema documents.

A valid example of the above mode:

<?xml version="1.0" encoding="utf-8" ?>
<name>
  <first>santld</first>
  <middle>
    <nameInChina>San</nameInChina>
  </middle>
  <last>wang</last>
</name>

2. Empty content model (empty)

Sometimes an element has no content at all and its content model is empty. In order to define the type with empty content, we can first define an element, which can only contain child elements but not element content, and then do not define any child elements. In this way, we can define elements with empty content model.

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="internationalPrice">
    <xsd:complexType>
      <xsd:complexContent>
        <xsd:restriction base="xsd:anyType">
          <xsd:attribute name="currency" type="xsd:string"/>
          <xsd:attribute name="value" type="xsd:decimal"/>
        </xsd:restriction>
      </xsd:complexContent>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

Valid XML documents are as follows:

<internationalPrice currency="ERU" value="/423.46"/>

Invalid document example:

<internationalPrice currency="ERU" value="/423.46"/>This is wrong</internationalPrice>

3. Mixed content model

It contains text, content, and attributes. Setting the value of the mixed attribute to true on the complexType element declares a mixed content model. For example:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="contact">
    <xsd:complexType mixed="true">
      <xsd:sequence>
        <xsd:element name="first" type="xsd:string" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

An effective example of the above mode is as follows:

<?xml version="1.0" encoding="utf-8" ?>
<contact>
  My first is <first>Santld</first>.
</contact>

4, Create XSD Schema with Visual Studio Designer

It is easy to create XSD Schema with Visual Studio. Because the IDE provides visualization tools for building elements, simple types, complex types, and so on. First, add a new Schema file.   

The name of the English version is XML Schema, and the Chinese version is XML Schema. Strangely, according to the book, after adding an XML Schema file, there will be many tools in the toolbox, but no tools are added in my Visual Studio 2010. Leave it here for later supplement.

5, A Net validation XML document

In order to associate external XSD Schema files in XML documents, corresponding modifications should be made to XML documents and XSD Schema files. The specific modifications are as follows:

XML file:

<?xml version="1.0" encoding="utf-8" ?>
<person xmlns="http://www.xxx.com/xxx">
  <name>Zhang Fei 1111111</name>
  <age>24</age>
</person>

XML Schema file:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.xxx.com/xxx">
  <xs:element name="person">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="name">
          <xs:simpleType>
            <xs:restriction base="xs:string">
              <xs:maxLength value="4"/>
              <xs:minLength value="2"/>
            </xs:restriction>
          </xs:simpleType>
        </xs:element>
        <xs:element name="age">
          <xs:simpleType>
            <xs:restriction base="xs:positiveInteger">
              <xs:maxExclusive value="100"/>
              <xs:minExclusive value="1"/>
            </xs:restriction>
          </xs:simpleType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Code files: XmlDocument validation files

        static void Main(string[] args)
        {
            XmlDocument doc = new XmlDocument();    //create documents
            doc.Schemas.Add(null, @"C:\Users\Administrator\Desktop\ConsoleApplication1\ConsoleApplication1\person.xsd");    //Add validation schema file, null, use default namespace
            doc.Load(@"C:\Users\Administrator\Desktop\ConsoleApplication1\ConsoleApplication1\person.xml");     //Load xml file
            doc.Validate(SettingsValidationEventHandler);   //Execute the validation operation. The error handling method is the parameter SettingsValidationEventHandler
            Console.WriteLine("Verification passed");      //This will only be performed if the verification passes
            Console.ReadKey();

        }

        static void SettingsValidationEventHandler(object sender, ValidationEventArgs e)
        {
            if (e.Severity == XmlSeverityType.Warning)
            {
                Console.Write("Warning message: ");
                Console.WriteLine(e.Message);

            }
            else if (e.Severity == XmlSeverityType.Error)
            {
                Console.Write("error message: ");
                Console.WriteLine(e.Message);
            }
            else 
            {
            
            }
            Console.ReadKey();
        }

Code file: XmlReader version:

        static void Main(string[] args)
        {
            XmlReaderSettings Settings = new XmlReaderSettings();   //
            Settings.Schemas.Add(null, @"C:\Users\Administrator\Desktop\ConsoleApplication1\ConsoleApplication1\person.xsd");
            Settings.ValidationType = ValidationType.Schema;
            Settings.ValidationEventHandler += new ValidationEventHandler(SettingsValidationEventHandler);
            XmlReader reader = XmlReader.Create(@"C:\Users\Administrator\Desktop\ConsoleApplication1\ConsoleApplication1\person.xml", Settings);
            while (reader.Read())
            { }
            reader.Close();
            Console.WriteLine("Validation succeeded!");
            Console.ReadKey();
        }

        static void SettingsValidationEventHandler(object sender, ValidationEventArgs e)
        {
            if (e.Severity == XmlSeverityType.Warning)
            {
                Console.Write("Warning message: ");
                Console.WriteLine(e.Message);

            }
            else if (e.Severity == XmlSeverityType.Error)
            {
                Console.Write("error message: ");
                Console.WriteLine(e.Message);
            }
            else 
            {
            
            }
            Console.ReadKey();
        }