Generating Restrictions in XML Schema Dynamically Using VB.NET 2005: Preliminaries
This is the first article in a series concentrating on generating restrictions in XML Schema dynamically using Visual Basic 2005. The series is mainly targeted at those who are familiar with XML, XML Schema and the .NET framework.
A downloadable file for this article is available here.
If you are new to XML, there exist several articles on XML alone on this web site (try “igrep”). If you are new to XML Schema, I strongly suggest you go through my series “Designing your own XML Schema.” If you are new to generating XML Schema using .NET, I suggest you go through my series “Generating XML schema dynamically using VB.NET 2005.”
The entire solution for this article was developed using Visual Studio 2005 Professional Edition on Windows Server 2003 standard edition. Some examples in this series may not compile successfully using Visual Studio 2003, as some of the features in .NET 1.1 turned out to be obsolete in .NET 2.0. For complete details you can refer to this link: http://go.microsoft.com/fwlink/?linkid=14202. Please note that some of the examples in this series may not be practical. Those were designed only for explaining the particular concept.
Restrictions (or constraints) in XML Schema: A sample schema
Since I already covered “restrictions” in my series “designing your own XML schema,” I will not repeat the information. Here we shall work directly with a sample scenario.
I would like to have an element “AGE” present in my XML Schema. I can assign a data type “integer” to it. But this is not sufficient because I would like to have a value between 0 and 100 (whereas an integer would accept more than that). This means a “restriction” is necessary. Let us consider the following XML Schema, which can do something better:
Let us concentrate on the “age” element. It stays under the “Employee” element. Its “simpleType” (or data type) is defined as an integer type. And finally, we applied the “restriction” by specifying the maximum value as follows:
<xs:element name="age">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:maxInclusive value="100" />
</xs:restriction>
</xs:simpleType>
</xs:element>
You should also observe that “Name” and “Age” are defined with “simple types” rather than with “complex types.” The only complex elements are “Organization” and “Employee.” You can use “Exclusive” or “Inclusive” according to your requirements (they can even be interchanged). But care should be taken while defining the same (especially when using tools).
In the previous section, I already listed a schema which we would like to generate dynamically. The following is the complete VB.NET code to generate the previous schema:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.TextBox1.Text = ""
Dim schema As New XmlSchema()
Dim eOrganization As New XmlSchemaElement
schema.Items.Add(eOrganization)
eOrganization.Name = "Organization"
Dim ctOrganization As New XmlSchemaComplexType
eOrganization.SchemaType = ctOrganization
Dim sqOrganization As New XmlSchemaSequence
ctOrganization.Particle = sqOrganization
Dim eEmployee As New XmlSchemaElement()
sqOrganization.Items.Add(eEmployee)
eEmployee.Name = "Employee"
eEmployee.MaxOccursString = "unbounded"
Dim ctEmployee As New XmlSchemaComplexType()
eEmployee.SchemaType = ctEmployee
Dim sqEmployee As New XmlSchemaSequence
ctEmployee.Particle = sqEmployee
Dim eName As New XmlSchemaElement()
sqEmployee.Items.Add(eName)
eName.Name = "Name"
eName.SchemaTypeName = New XmlQualifiedName("string", "http://www.w3.org/2001/XMLSchema")
Dim eAge As New XmlSchemaElement()
sqEmployee.Items.Add(eAge)
eAge.Name = "Age"
Dim simpleType As New XmlSchemaSimpleType()
eAge.SchemaType = simpleType
Dim restriction As New XmlSchemaSimpleTypeRestriction()
simpleType.Content = restriction
restriction.BaseTypeName = New XmlQualifiedName ("integer", "http://www.w3.org/2001/XMLSchema")
Dim maxInclusive As New XmlSchemaMaxInclusiveFacet()
restriction.Facets.Add(maxInclusive)
maxInclusive.Value = "100"
Dim eID As New XmlSchemaAttribute()
ctEmployee.Attributes.Add(eID)
eID.Name = "ID"
eID.Use = XmlSchemaUse.Required
eID.SchemaTypeName = New XmlQualifiedName("int", "http://www.w3.org/2001/XMLSchema")
Dim nsmgr As New XmlNamespaceManager(New NameTable())
I purposefully excluded the “import” statements, because I already covered them in my previous articles. You can find a step-by-step explanation of the above code in the next section.
This section explains the code fragment listed in the previous section. Let us examine it part by part. I am excluding some of the parts which are already explained in previous articles.
Since the “Employee” element itself is of the complex type, we can add any number of child elements to it. Adding a “Name” element (child) to the “Employee” element looks like this:
Dim eName As New XmlSchemaElement()
sqEmployee.Items.Add(eName)
eName.Name = "Name"
eName.SchemaTypeName = New XmlQualifiedName("string", "http://www.w3.org/2001/XMLSchema")
And similarly I added another element, “Age,” as well. After adding all the elements (or child elements) to the “Employee” element, we need to add the required attribute (which is “ID”). The following code fragment shows how to add an attribute to a complex type of element:
Dim eID As New XmlSchemaAttribute()
ctEmployee.Attributes.Add(eID)
eID.Name = "ID"
eID.Use = XmlSchemaUse.Required
eID.SchemaTypeName = New XmlQualifiedName("int", "http://www.w3.org/2001/XMLSchema")
And finally we need to focus on the restriction we applied to the XML schema. The following is the main code fragment which implements the restriction.
Dim simpleType As New XmlSchemaSimpleType()
eAge.SchemaType = simpleType
Dim restriction As New XmlSchemaSimpleTypeRestriction()
simpleType.Content = restriction
restriction.BaseTypeName = New XmlQualifiedName ("integer", "http://www.w3.org/2001/XMLSchema")
Dim maxInclusive As New XmlSchemaMaxInclusiveFacet()
restriction.Facets.Add(maxInclusive)
maxInclusive.Value = "100"
To apply the restriction, first of all we need to create a “simple type.” The content of the simple type needs to be assigned with an object based on the “XmlSchemaSimpleTypeRestriction” class. Within the above code fragment, I created an object “restriction” based on the same class and assigned it to the “content” property of the simple type.
Any “restriction” is generally based on a certain base type and in this case, the base type would be an “integer” type. Once the base type is fixed, we can now attach the appropriate facet for the restriction. I used the “maxInclusive” facet which restricts based on the maximum value (inclusive of the value itself). The maximum value to accept into the “Age” element is defined as “100.” An acceptable XML document conforming to the above XML Schema would be as follows:
<?xml version="1.0" encoding="UTF-8"?>
<Organization xmlns:xsi="http://www.w3.org/2001/XMLSchema- instance" xsi:noNamespaceSchemaLocation="C:\Documents and Settings\Administrator\Desktop\ForDec\ForDec\XSLT\XMLExamples\02 \Sample.xsd">
I gave an example covering the “Age” element previously. It is not going to be a complete solution yet. We specified only the maximum value (and forgot about the minimum value). So, let us make tiny modifications (especially for the “Age” element) to our schema so that it looks like the following, which contains two facets now:
<xs:element name="age">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minExclusive value="0" />
<xs:maxInclusive value="100" />
</xs:restriction>
</xs:simpleType>
</xs:element>
Within the above XML Schema, I managed to have two facets be implemented. Now, with the above two facets we tightly restrict the “Age” element to have a value only between 1 and 100. Now, let us see how we can achieve the same dynamically using .NET.
You can modify the code fragment presented in the previous sections as follows:
Dim restriction As New XmlSchemaSimpleTypeRestriction()
simpleType.Content = restriction
restriction.BaseTypeName = New XmlQualifiedName ("integer", "http://www.w3.org/2001/XMLSchema")
Dim minExclusive As New XmlSchemaMinExclusiveFacet()
restriction.Facets.Add(minExclusive)
minExclusive.Value = "0"
Dim maxInclusive As New XmlSchemaMaxInclusiveFacet()
restriction.Facets.Add(maxInclusive)
maxInclusive.Value = "100"
And that would achieve what we desired. Once you execute the above code, you should be able to see the following output of the XML Schema:
This has caused a lot of confusion among several beginners when they design a new XML Schema. Let us consider the following fragment of XML Schema:
<xs:element name="age">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minExclusive value="1" />
<xs:maxExclusive value="100" />
</xs:restriction>
</xs:simpleType>
</xs:element>
According to the above code fragment, both values are “exclusive” during validation. That means the “Age” element can have data between 2 and 99 (both inclusive) only. Let us consider the following code fragment:
<xs:element name="age">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minInclusive value="1" />
<xs:maxInclusive value="100" />
</xs:restriction>
</xs:simpleType>
</xs:element>
According to the above code fragment, both values are “inclusive” during validation. That means the “Age” element can have data between 1 and 100 (both inclusive) only. We can also mix them according to our necessity. Let us consider the following code fragment:
<xs:element name="age">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minExclusive value="1" />
<xs:maxInclusive value="100" />
</xs:restriction>
</xs:simpleType>
</xs:element>
According to the above code fragment, the “Age” element can have data between 2 and 100 (both inclusive) only. Let us consider the following code fragment:
<xs:element name="age">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minInclusive value="1" />
<xs:maxExclusive value="100" />
</xs:restriction>
</xs:simpleType>
</xs:element>
According to the above code fragment, the “Age” element can have data between 1 and 99 (both inclusive) only.
I hope the above examples clear up any confusion among the usage of “Inclusive” and “Exclusive” facets available when making restrictions in XML Schema.
The upcoming article will dig further into the details of restrictions using .NET. So keep notified by signing up for a newsletter. Any comments, suggestions, feedback, bugs, errors, enhancements are highly appreciated at jag_chat@yahoo.com