A downloadable file for this article is available here.
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 the link http://go.microsoft.com/fwlink/?linkid=14202. Please note that some of the examples in this series may not be practical. They have been designed only for explaining the concept.
Generate XML Schema attributes dynamically using .NET framework: A sample schema
As I covered all the basics in my previous articles, we shall now focus on more practical “complex types” in XML Schema, supported with attributes as well. Let us consider the following XML Schema:
According to the above example, the document root element would be “Organization.” The element “Organization” internally can contain “Employee” elements. The element “Employee” internally contains two more elements, “Name” and “Age”. You should observe that there can be any number of “Employee” elements within the “Organization” 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.” The most important declaration within the above schema is as follows:
The above statement makes sure that every “Employee” element is provided with the attribute “ID” (which is of type “int”). To generate the above XML Schema dynamically, we can consider the complete code listed in the next section.
In the previous section, I already listed a schema which we would like to generate dynamically. The following is the complete VB.NET code needed 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"
eAge.SchemaTypeName = New XmlQualifiedName("int", "http://www.w3.org/2001/XMLSchema")
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, as 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. Let us take a look at the definitions of the main elements like “Organization”, “Employee” and so on.
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
The above creates a new element (root) “Organization,” defines it as a complex type, and internally contains the elements in the form of a sequence. The “Employee” element would look similar to the above element as follows:
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
The only extras in the above code fragment are the following:
Add the “Employee” element as an element inside the “Organization” element (second statement)
The “Employee” element could be repeated any number of times within the “Organization” element (fourth statement).
Besides the above two points, all the rest is the same. As 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 can be done as follows:
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 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")
According to the above code fragment, we create a new XML schema attribute (“eID”) and add it to the list of attributes related to the complex type of “Employee” element (second statement in the above code). I wanted to make sure that “ID” is a compulsory attribute to every “Employee” element (which is enforced in the fourth statement).
A reasonable 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">
Let us consider the following situation for an XML document:
<?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">
<Employee ID="1001" Name="Jag" Age="27" />
<Employee ID="1002" Name="Winner" Age="20" />
<Employee ID="1003" Name="Dhan" />
<Employee ID="1004" Name="aaa" />
<Employee ID="1005" Name="bbb" Age="72" />
<Employee ID="1006" Name="ccc" />
</Organization>
According to the above, we would have a single “Organization” element nested with several “Employee” elements. Even though the “Employee” element is of the complex type, it is trying to accept all of the information in the form of attributes (rather than child elements). This is quite different from the previous scenario. Another important issue is that the “Age” attribute is not compulsory (observe carefully the above XML document).
Now, how about the XML Schema for the above XML document? It would look something like the following:
Generate more XML Schema attributes dynamically using the .NET framework: source code
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 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 eName As New XmlSchemaAttribute()
ctEmployee.Attributes.Add(eName)
eName.Name = "Name"
eName.Use = XmlSchemaUse.Required
eName.SchemaTypeName = New XmlQualifiedName("string", "http://www.w3.org/2001/XMLSchema")
Dim eAge As New XmlSchemaAttribute()
ctEmployee.Attributes.Add(eAge)
eAge.Name = "Age"
eAge.SchemaTypeName = New XmlQualifiedName("int", "http://www.w3.org/2001/XMLSchema")
Dim nsmgr As New XmlNamespaceManager(New NameTable())
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 (and even above).
From the following code, you can observe that I removed the sequence particle related to the “Employee” element. It is just maintaining its own complex type:
Dim eEmployee As New XmlSchemaElement()
sqOrganization.Items.Add(eEmployee)
eEmployee.Name = "Employee"
eEmployee.MaxOccursString = "unbounded"
Dim ctEmployee As New XmlSchemaComplexType()
eEmployee.SchemaType = ctEmployee
We add the attribute “ID” to the “Employee” element as follows:
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")
You should also observe that attributes are to be added to a complex type and never to a sequence type. According to the above code fragment, we create a new XML schema attribute (“eID”) and add it to the list of attributes related to the complex type of “Employee” element (second statement in the above code). I wanted to make sure that “ID” is a compulsory attribute for every “Employee” element (which is enforced in the fourth statement). Similarly, I even defined “Name” and “Age” (but observe that “Age” is not enforced with “XmlSchemaUse.Required”).
We shall focus on “restrictions” in the up coming articles. So, stay tuned by signing up the newsletter. Any comments, suggestions, feedback, bugs, errors, enhancements are highly appreciated at jag_chat@yahoo.com