Characteristics of an XML Document |
|
Comments
Introduction
To differentiate the various nodes that belong to an XML file, they are classified by their category. The types of node are listed in the XmlNodeType enumeration.
Creating a Comment
A comment is a character, a line or a paragraph that is not considered as part of the XML code that needs to be processed. A comment allows you to insert notes or personal observations inside an XML file. For this reason, a commented section can be written any way you like. This means that a comment can include plain text, formulas, expressions, or even XML code as long as you know that that XML code will not be validated: it will be ignored by the parser.
To manually create a comment, you use the following formula:
<!-- Blah Blah Blah ->
Between <!-- and -->, any text in that section is considered a comment and you can include anything you want. Both sections of the comment use two dashes, not more, not less. Here is an example:
<?xml version="1.0" encoding="UTF-8"?> <!-- In this time sheet, a regular day is 0 to 8 hours. Overtime is any time over 8 hours. --> <TimeSheets> <TimeSheet> <TimeSheetID>1</TimeSheetID> <EmployeeNumber>606384</EmployeeNumber> <StartDate>2015-06-01</StartDate> <Week1Monday>0</Week1Monday> <Week1Tuesday>0</Week1Tuesday> <Week1Wednesday>0</Week1Wednesday> <Week1Thursday>0</Week1Thursday> <Week1Friday>0</Week1Friday> <Week1Saturday>8</Week1Saturday> <Week1Sunday>8</Week1Sunday> <Week2Monday>0</Week2Monday> <Week2Tuesday>0</Week2Tuesday> <Week2Wednesday>0</Week2Wednesday> <Week2Thursday>0</Week2Thursday> <Week2Friday>0</Week2Friday> <Week2Saturday>8</Week2Saturday> <Week2Sunday>8</Week2Sunday> </TimeSheet> <TimeSheet> <TimeSheetID>2</TimeSheetID> <EmployeeNumber>952748</EmployeeNumber> <StartDate>2015-06-01</StartDate> <Week1Monday>8</Week1Monday> <Week1Tuesday>8</Week1Tuesday> <Week1Wednesday>8</Week1Wednesday> <Week1Thursday>8</Week1Thursday> <Week1Friday>8</Week1Friday> <Week1Saturday>0</Week1Saturday> <Week1Sunday>0</Week1Sunday> <Week2Monday>8</Week2Monday> <Week2Tuesday>8</Week2Tuesday> <Week2Wednesday>8</Week2Wednesday> <Week2Thursday>8</Week2Thursday> <Week2Friday>8</Week2Friday> <Week2Saturday>0</Week2Saturday> <Week2Sunday>0</Week2Sunday> </TimeSheet> </TimeSheets>
To support comments, the System.Xml provides a class named XmlComment. To allow you to programmatically create a comment, the XmlDocument class is equipped with a method named CreateComment. Its signature is:
Public Overridable Function CreateComment(ByVal data As String) As XmlComment
This method takes as argument the text that would go into the commented section. After calling it, if the method succeeds, which it usually does, it returns the XmlComment object that was created. Here is an example of creating a comment:
TimeZones.xml
<?xml version="1.0" encoding="utf-8"?> <time-zones> <zone> <name initials="CST">Central Standard Time</name> <utc>-06:00</utc> <states-and-territories> <state inclusion="Split" cb-region="East South Central" bea-region="Southeast">Alabama</state> <state inclusion="Entirely" cb-region="West South Central" bea-region="Southeast">Arkansas</state> <state inclusion="Split" cb-region="South Atlantic" bea-region="Southeast">Florida</state> <state inclusion="Entirely" cb-region="West North Central" bea-region="Plains">Minnesota</state> <state inclusion="Entirely" cb-region="East North Central" bea-region="Great Lakes">Ohio</state> </states-and-territories> </zone> <zone> <name initials="EST">Eastern Standard Time</name> <utc>-05:00</utc> <states-and-territories> <state inclusion="Split" cb-region="East South Central" bea-region="Southeast">Alabama</state> <state inclusion="Entirely" cb-region="New England">Maine</state> <state inclusion="Entirely" cb-region="New England" bea-region="New England">Vermont</state> <state inclusion="Split" cb-region="South Atlantic" bea-region="Southeast">Florida</state> </states-and-territories> </zone> </time-zones>
<%@ Page Language="VB" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Xml" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title>Time Zones</title>
</head>
<body>
<h3>Time Zones</h3>
<%
Dim xnTimeZone As XmlNode
Dim xcDescription As XmlComment
Dim xnlTimeZones As XmlNodeList
Dim xdTimeZones As XmlDocument = New XmlDocument()
Dim strFileName = Server.MapPath("App_Data/TimeZones.xml")
If File.Exists(strFileName) Then
Using fsTimeZones = New FileStream(strFileName, FileMode.Open, FileAccess.Read)
xdTimeZones.Load(fsTimeZones)
End Using
xcDescription = xdTimeZones.CreateComment("The Eastern Standard Time zone covers 17 US states " +
"on the east section of the country, some eastern " +
"parts of Canada, a Mexican state, the country of " +
"Panama, and some Caribbean islands.")
' Get a list of elements whose names are "name"
xnlTimeZones = xdTimeZones.GetElementsByTagName("name")
' Visit each time zone element
For Each xnTimeZone In xnlTimeZones
' Look for a time zone named Eastern Standard Time
If xnTimeZone.InnerText = "Eastern Standard Time" Then
'MessageBox.Show(xnTimeZone.ParentNode.InnerXml)
xnTimeZone.ParentNode.InsertBefore(xcDescription, xnTimeZone)
Using fsTimeZones = New FileStream(strFileName, FileMode.Create, FileAccess.Write)
xdTimeZones.Save(fsTimeZones)
End Using
End If
Next
End If
%>
</body>
</html>
This would produce:
<?xml version="1.0" encoding="utf-8"?>
<time-zones>
<zone>
<name initials="CST">Central Standard Time</name>
<utc>-06:00</utc>
<states-and-territories>
<state inclusion="Split" cb-region="East South Central" bea-region="Southeast">Alabama</state>
<state inclusion="Entirely" cb-region="West South Central" bea-region="Southeast">Arkansas</state>
<state inclusion="Split" cb-region="South Atlantic" bea-region="Southeast">Florida</state>
<state inclusion="Entirely" cb-region="West North Central" bea-region="Plains">Minnesota</state>
<state inclusion="Entirely" cb-region="East North Central" bea-region="Great Lakes">Ohio</state>
</states-and-territories>
</zone>
<zone>
<!--The Eastern Standard Time zone covers 17 US states on the east section of the country, some eastern parts of Canada, a Mexican state, the country of Panama, and some Caribbean islands.-->
<name initials="EST">Eastern Standard Time</name>
<utc>-05:00</utc>
<states-and-territories>
<state inclusion="Split" cb-region="East South Central" bea-region="Southeast">Alabama</state>
<state inclusion="Entirely" cb-region="New England">Maine</state>
<state inclusion="Entirely" cb-region="New England" bea-region="New England">Vermont</state>
<state inclusion="Split" cb-region="South Atlantic" bea-region="Southeast">Florida</state>
</states-and-territories>
</zone>
</time-zones>
Like any other part of an XML file, a comment is represented by the XmlComment.Name property. This allows you to retrieve the name of a comment that is included in the document.
Introduction
Except for comments, the parser is used to "scan" the whole XML file to analyze it. Every tag is then interpreted. As we mentioned already, the value of each tag can be displayed in a browser between its opening and its closing tag, and the browser uses different font styles to make a distinction. When creating some tags and some sections of the file, you may want the parser to consider those particular tags and sections as regular text. That is, you may want the parser to treat a certain tag and its value as if it were regular text even though it is created as an XML file.
To prevent the parser from interpreting a tag regularly but to treat that tag and its value as regular text, you can create it in a CDATA section.
Creating a CDATA Section
To do this, create a section that starts with <![CDATA[, followed by anything you want, and ending with ]]>. The formula used is:
<![CDATA[ Blah Blah Blah ]]>
Between <![CDATA[ and ]]>, you can type anything, including one or more normal XML tags. Here is an example:
<?xml version="1.0" encoding="utf-8"?> <!-- In this collection, we will keep each title "as is" --> <videos> <![CDATA[<VdoColl>Collection of Videos</VdoColl>]]> <video> <title>The Distinguished Gentleman</title> <director>Jonathan Lynn</director> <length>112 Minutes</length> <format>DVD</format> <rating>R</rating> </video> <video> <title>Her Alibi</title> <director>Bruce Beresford</director> <length>94 Mins</length> <format>DVD</format> <rating>PG-13</rating> </video> </videos>
To support CDATA section, the .NET Framework provides a class named XmlCDataSection. To allow you to programmatically create a CDATA section, the XmlDocument class is equipped with the CreateCDataSection() method. Its signature is:
Public Overridable Function CreateCDataSection(ByVal data As String) As XmlCDataSection
Here is an example of calling this method:
College Park Auto-Parts: auto-parts.xml
<?xml version="1.0" encoding="utf-8"?> <auto-parts business="College Park Auto-Parts"> <auto-part item-number="937418"> <year>2012</year> <make>Toyota</make> <model trim="LE" engine="1.8L L4" body-style="4-Speed Automatic Transaxle U341E">Corolla</model> <category>Shocks, Struts & Suspension</category> <part-name>KYB SM5215 Strut mount</part-name> <unit-price status="New">58.85</unit-price> </auto-part> <auto-part item-number="280486"> <year>2015</year> <make>Ford</make> <model>Escape</model> <category>Brake System</category> <part-name>Power Stop (16-1044) Z16 Ceramic Brake Pad</part-name> <unit-price status="Refurbished">44.45</unit-price> </auto-part> <auto-part item-number="580686"> <year>2012</year> <make>Toyota</make> <model trim="SE" engine="2.0L L4 Gas" body-style="6-Speed Automatic Transaxle 6F">Corolla</model> <category>Air Filters</category> <part-name>FRAM CF10285 Fresh Breeze Cabin Air Filter</part-name> <unit-price status="New">14.15</unit-price> </auto-part> </auto-parts>
College Park Auto-Parts: np.aspx
<%@ Page Language="VB" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Xml" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title>College Park Auto-Parts - Part Update</title>
</head>
<body>
<h3>College Park Auto-Parts - Part Update</h3>
<%
Dim xdAutoParts As New XmlDocument()
Dim xcsDescription As XmlCDataSection
Dim strFileName = Server.MapPath("App_Data/auto-parts.xml")
If File.Exists(strFileName) Then
Using fsAutoParts = New FileStream(strFileName, FileMode.Open, FileAccess.Read)
xdAutoParts.Load(fsAutoParts)
End Using
xcsDescription = xdAutoParts.CreateCDataSection("<auto-part item-number='000000'>" & vbCrLf &
" <year>1900</year>" & vbCrLf &
" <make>Manufacturer</make>" & vbCrLf &
" <model trim='Manufaturer classification' engine='Type of capacity/power' body-style='Some specifications'>Particular Model</model>" & vbCrLf &
" <category>Type of part to add or replace</category>" & vbCrLf &
" <part-name>Object name and/or short description</part-name>" & vbCrLf &
" <unit-price status='New/Used/Refurbished'>0.00</unit-price>" & vbCrLf &
"</auto-part>" + Environment.NewLine)
xdAutoParts.DocumentElement.AppendChild(xcsDescription)
Using fsAutoParts = New FileStream(strFileName, FileMode.Create, FileAccess.Write)
xdAutoParts.Save(fsAutoParts)
End Using
End If
%>
</body>
</html>
This would produce:
<?xml version="1.0" encoding="utf-8"?>
<auto-parts business="College Park Auto-Parts">
<auto-part item-number="937418">
<year>2012</year>
<make>Toyota</make>
<model trim="LE" engine="1.8L L4" body-style="4-Speed Automatic Transaxle U341E">Corolla</model>
<category>Shocks, Struts & Suspension</category>
<part-name>KYB SM5215 Strut mount</part-name>
<unit-price status="New">58.85</unit-price>
</auto-part>
<auto-part item-number="280486">
<year>2015</year>
<make>Ford</make>
<model>Escape</model>
<category>Brake System</category>
<part-name>Power Stop (16-1044) Z16 Ceramic Brake Pad</part-name>
<unit-price status="Refurbished">44.45</unit-price>
</auto-part>
<auto-part item-number="580686">
<year>2012</year>
<make>Toyota</make>
<model trim="SE" engine="2.0L L4 Gas" body-style="6-Speed Automatic Transaxle 6F">Corolla</model>
<category>Air Filters</category>
<part-name>FRAM CF10285 Fresh Breeze Cabin Air Filter</part-name>
<unit-price status="New">14.15</unit-price>
</auto-part><![CDATA[<auto-part item-number='000000'>
<year>1900</year>
<make>Manufacturer</make>
<model trim='Manufaturer classification' engine='Type of capacity/power' body-style='Some specifications'>Particular Model</model>
<category>Type of part to add or replace</category>
<part-name>Object name and/or short description</part-name>
<unit-price status='New/Used/Refurbished'>0.00</unit-price>
</auto-part>
]]></auto-parts>
This class is equipped with a Name property that allows you t retrieve the name of a CDATA section in an XmlDocument object.
XML Namespaces
Introduction
The Internet is filled with XML documents. Even inside of a company or a department, many people create XML or XML-types of documents on a daily basis. One of the things that these many documents share is that they use same words or names, by coincidence or without any intention. The ultimate problem is that, when two XML documents are accessed in the same application, if those two documents use the same name, there could be a conflict of names.
A namespace is a technique of qualifying a name so that it would not conflict with another name. Normally, you should already be familiar with namespaces because they are used in F#. The concept is primarily the same in XML. You create a namespace in your XML document so that its elements and attributes can be accessed outside that document without worrying about name conflicts because the names of your document will be qualified.
The Construction of a Namespace
In XML, a namespace is made of two parts: a namespace name and a local name.
As you may know already, to open an XML document, you can use a browser. For example, if you have a document named employees.xml and that is hosted on the web site of funfunfun.com, you can open it using http:'www.funfunfun.com/employees.xml. Another web site, such as blahblahblah.com, can have a file named employees.xml and that file can be accessed with http:'www.blahblahblah.com/employees.xml.
Creating a Namespace
A namespace is created as an XML attribute. This means that you must create an element that has a name. Here is an example:
<business></business>
The keyword to create an XML namespace is xmlns. The formula to create a namespace is:
PrefixAttributeName | DefaultAttributeName Name
This means that you primarily have two options:
<business xmlns:CarRental></business>
In an XML namespace, binding consists of associating an element to a prefix. To create this binding, you must assign a value to your namespace. The value must be a Uniform Resource Identifier (URI), which is an address of a document that resides somewhere, on the World Wide Web or in a computer. When it comes to XML, the URI must identify a namespace.
There are two types of URI documents:
http:'www.csharpkey.com/visualcsharp http:'www.functionx.com/access/topics
urn:www.csharpkey.com:visualcsharp urn:www-functionx-com:access.topics
Normally, in order
Any of them can be used to identify a namespace. Remember that, when creating a namespace, you have two options:
<business xmlns:CarRental="http:'www.abcd1234.com/rent"></business>
<business xmlns="http:'www.abcd1234.com/"></business>
In this case, the URL is referred to as the default namespaceThis whole formula is referred to as a namespace binding. In this formula, xmlns and what follows it is not considered an attribute in the traditional sense. This means that if you try to access the collection of attributes of the tag, xmlns and its expression will not be considered as a member of that collection.
In addition to these, there are a few rules you must follows:
<business xmlns:xml="http:'www.abcd1234.com/rent"></business>
<business xmlns:xmlns="http:'www.abcd1234.com/rent"></business>
To own a URL (such as a website), you must register a domain name with an authority (such as Network Solutions or GoDaddy, etc). Once you own the name, you can use it as you see fit. For example, inside your website, you can create directories and sub-directories any way you want. To communicate a URL to other people, you give the address. When it comes to namespaces, you can also create your own, using a domain name you will have registered. As an alternative, you can use namespaces that other people have created. As mentioned above the W3C organization provides a few namespaces already. Microsoft also provides many already created namespaces. We will come back to them.
Using a Namespace
After creating a namespace, you can use the elements to which it refers. When creating an XML element, precede the tag's name with a prefix of the namespace and a colon ":". After the name of the tag, define the namespace that contains xmlns: followed by the prefix and assign the namespace's URL to it. Here is an example:
<?xml version="1.0" encoding="utf-8" ?>
<car:status xmlns:business="http:'www.functionx.com/rent" />
If you decide to close the tag with an end tag, you must use the tag name:prefix formula. Here is an example:
<?xml version="1.0" encoding="utf-8" ?>
<car:status xmlns:business="http:'www.functionx.com/rent"></car:status>
Remember that the xmlns expression is not an attribute. If you want an actual attribute, you can add it. Here is an example:
<?xml version="1.0" encoding="utf-8" ?>
<car:status xmlns:business="http:'www.functionx.com/rent" available="Yes"></car:status>
In the same way, you can add as many attributes as you want.
If you want to create a tag that has an attribute, after the name of the tag, type the prefix you had defined for the namespace, followed by :, followed by the attribute's name and assign the desired value to it. Optionally, you can assign the desired value to the attribute. If necessary, close the tag and optionally specify its value. Here is an example:
<?xml version="1.0" encoding="utf-8" ?>
<business xmlns:CarRental="http:'www.functionx.com/rent">
<car CarRental:status="Available">Ford Escort</car>
</business>
To access one of the names, you must qualify it. To do this, type the name of the prefix, followed by :, and followed by the name of the element.
Introduction to XML Schemas
Definition
We know how to create XML elements and how to add values to them. Some values appeared as regular strings. Some appeared as number, and so on. In reality, we did not define what type each value was. In fact, we could have a child node whose value appeared as a string while the same child node in the element would appear as a numbers. An XML schema is a document that specifies the type of value that each element of the corresponding XML document uses. This means that an XML schema must provide at least two pieces of information: the XML document that the schema refers to and the list of elements defined by the schema.
Introduction to Creating an XML Schema
Like an XML file, an XML schema is a text-based document made of tags. You can start the document with a document type definition (DTD) that including encoding:
<?xml version="1.0" encoding="utf-8"?>
After that line, you will create the elements of the document. The first characteristic of an XML schema document is that it must specify a namespace. The namespace is defined in a document that specifies the types of values used in the document. As seen in our introduction to namespaces, you must decide about the prefix you will use in the various tags of the document. By convention, most people use either xs, which stands of XML Schema, or xsd, which stands for XML Schema Definition. Here is an example that uses xs:
<?xml version="1.0" encoding="utf-8"?>
<xs>
As mentioned in our review of namespaces, the prefix must be followed by a colon and a name for the tag. In a typical XML schema, the first tag is named schema:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema>
As mentioned already, you must specify the namespace you will use. As mentioned in our study of namespaces, you create an attribute what uses xmlns as its prefix followed by a column and the prefix previously defined:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs>
You must assign the URL of the namespace to that attribute.
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="">
After creating the document, you should (must) save it and give it a name. An XML schema file has the extension .xsd.
Built-In Schemas
As mentioned already, the primary role of an XML schema is to define the types of values used in an XML document. There are various types of values that can be used in an XML document. Instead of defining your own types of values, many people and companies have already created XML schemas that you can simply use in your project. We refer to these as built-in XML schemas.
Among others, both the W3C consortium and Microsoft have already created XML schemas you can use. To see a list of built-in XML schemas, if you are working in Microsoft Visual Studio, first create or open an XML file. On the main menu, click XML -> Schemas... This would open the XML Schemas dialog box
To use any of these schemas, assign it to your xmlns:Prefix attribute. Here is an example:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http:'www.w3.org/2001/XMLSchema">
You can use one of the built-in schemas of the XML Schemas dialog box. You can also use more than namespace. To do this, create one schema tag and add each desired namespace. Here is an example:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http:'www.w3.org/2001/XMLSchema"
xmlns:xs="http:'www.w3.org/XML/1998/namespace"
xmlns:xs="http:'schemas.microsoft.com/xsd/catalog">
Notice that, in the XML Schemas dialog box, you can add a new one by clicking Add, locating, and then selecting the file.
Introduction to Creating a Tag in an XML Schema
Consider the following XML document:
<?xml version="1.0" encoding="utf-8"?> <video />
As mentioned already, to create its corresponding XML schema, start a text-based document that contains a DTD and a tag that specifies the foundational namespace. Of course, this tag must be closed. Here is an example:
<?xml version="1.0" encoding="utf-8"?> <xs:schema xmlns:xs="http:'www.w3.org/2001/XMLSchema"> </xs:schema>
Between the start and the end tags, you must specify the necessary tag. Since the schema is tied to the XML tag, it must include a tag for each of the XML elements. Each tag must start with the prefix, a column, and the keyword element. This would be done as follows:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http:'www.w3.org/2001/XMLSchema">
<xs:element ... >
</xs:schema>
To indicate what element the tag is referring to, you use name="" and, in the quotes, insert the name of the element from the XML document. Here is an example:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http:'www.w3.org/2001/XMLSchema">
<xs:element name="video">
</xs:schema>
As seen in our introductions to XML, you must close the tag and you have two options:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http:'www.w3.org/2001/XMLSchema">
<xs:elementname="video" />
</xs:schema>
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http:'www.w3.org/2001/XMLSchema">
<xs:element name="video">
</xs:element>
</xs:schema>
Characteristics of Tags of an XML Schema
Simple Types
In programming languages, a data type is a word or a group of words that indicates the amount of computer memory necessary to store a certain value or a certain kind of value. A value can be considered as a character, a group of characters (also called a string), a number, a date, etc. In XML, these are referred to as simple types. Consider the following XML document:
<?xml version="1.0" encoding="utf-8" ?> <video>The Distinguished Gentleman</video>
Notice that it contains only one element, that element has a value, and it does not have any child node. One of the rules of simple types is that their correspond node cannot have a child element. In the same way, an element of simple type cannot have an attribute.
Instead of defining your own simple types, you can use a built-in schema that already has the definitions you will need and you can simply use its data types. To specify the data type used by an element, in the XML schema and in the start-tag of the element, create an attribute whose name is type. Assign a string that contains the name of the prefix, followed by a colon, and followed by the data type. This would be done as follows:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http:'www.w3.org/2001/XMLSchema">
<xs:element name="video" type="xs:DataType">
</xs:element>
</xs:schema>
As mentioned already, a data type is primarily represented by a name but it may also have some internal characteristics that express how the data type functions. A number is referred to as signed if it can be represented with a leading sign as + or -, which means the number can be positive (from 0 up) or negative (from 0 down). When no leading sign is used, the number is considered positive. A number is reffered to as unsigned if it is positive.
The most common data types used for values of XML elements are:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http:'www.w3.org/2001/XMLSchema">
<xs:element name="video" type="xs:string">
</xs:element>
</xs:schema>
If none of the built-in types suits you, you can create your own.
Complex Types
Consider the following XML document:
<?xml version="1.0" encoding="utf-8" ?> <video> <title>The Distinguished Gentleman</title> <director>Jonathan Lynn</director> </video>
Notice that the video element has two child elements named title and director. When an XML element has a child element, that parent is said to have a complex type. In your XML schema, to create a tag for a parent element, create a tag named complexType and close it. This would be done as follows:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http:'www.w3.org/2001/XMLSchema">
<xs:element name="video">
<xs:complexType></xs:complexType>
</xs:element>
</xs:schema>
Between the start and end-tags of the complex type, you will create the tag(s) for the child element. But first, you must indicate that you are about to specify the order of the child elements. This is done by creating a tag named sequence. This can be done as follows:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http:'www.w3.org/2001/XMLSchema">
<xs:element name="video">
<xs:complexType>
<xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Remember that a parent element can have a value. Here is an example:
<?xml version="1.0" encoding="utf-8" ?>
<video>The Distinguished Gentleman
<director>Jonathan Lynn</director>
</video>
When create a schema for the element, add a name flag and assign the name of the element to it. Here is an example:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http:'www.w3.org/2001/XMLSchema">
<xs:element name="video">
<xs:complexType>
<xs:sequence name="video">
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Between the start and the end tags of the sequence, create a simple type tag for each child element of the corresponding complex tag. Here is an example:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http:'www.w3.org/2001/XMLSchema">
<xs:element name="video">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string" />
<xs:element name="director" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
The sequence tag indicates in what order the tag should appear in the XML document.
Consider the following XML document:
<?xml version="1.0" encoding="utf-8" ?> <videos> <video> <title>The Distinguished Gentleman</title> <director>Jonathan Lynn</director> <length>112</length> <rating>R</rating> <widescreen>true</widescreen> </video> <video> <title>Godzilla</title> <director>Roland Emmerich</director> <length>139</length> <rating>PG-13</rating> </video> </videos>
From what we have learned so far (namespaces, prefixes, the schema keyword, the element keyword, the complexType keyword, and the sequence keyword), it schema document can be created as follows:
<?xml version="1.0" encoding="utf-8"?> <xs:schema xmlns:xs="http:'www.w3.org/2001/XMLSchema"> <xs:element name="videos"> <xs:complexType> <xs:sequence> <xs:element name="video"> <xs:complexType> <xs:sequence> <xs:element name="title" type="xs:string" /> <xs:element name="director" type="xs:string" /> <xs:element name="length" type="xs:unsignedInt" /> <xs:element name="rating" type="xs:string" /> <xs:element name="widescreen" type="xs:boolean" /> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
Now consider the following XML document:
<?xml version="1.0" encoding="utf-8" ?> <videos> <video> <title>The Distinguished Gentleman</title> <director>Jonathan Lynn</director> <length>112</length> <actors> <actor>Eddie Murphy</actor> <actor>Lane Smith</actor> <actor>Sheryl Lee Ralph</actor> </actors> <rating>R</rating> <widescreen>false</widescreen> </video> <video> <title>Godzilla</title> <director>Roland Emmerich</director> <length>139</length> <actors> <actor>Matthew Broderick</actor> <actor>Jean Reno</actor> </actors> <rating>PG-13</rating> <widescreen>true</widescreen> </video> </videos>
Notice that the actors element, which is nested in the video element, has children elements of its own. For any node that has at least one child node, create a complexType start-tag and close it. Inside this complex type, create a sequence start-tag and close it. Inside the new sequence tag, create an element tag for each child element and specify its data type. Here is an example:
<?xml version="1.0" encoding="utf-8"?> <xs:schema xmlns:xs="http:'www.w3.org/2001/XMLSchema"> <xs:element name="videos"> <xs:complexType> <xs:sequence> <xs:element name="video"> <xs:complexType> <xs:sequence> <xs:element name="title" type="xs:string" /> <xs:element name="director" type="xs:string" /> <xs:element name="length" type="xs:unsignedByte" /> <xs:element name="actors"> <xs:complexType> <xs:sequence> <xs:element name="actor" type="xs:string" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="rating" type="xs:string" /> <xs:element name="widescreen" type="xs:boolean" /> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
XML Attributes and Schemas
As you are aware already, an XML element can have one or more attributes. Here is an example:
<?xml version="1.0" encoding="utf-8" ?>
<video title="The Distinguished Gentleman" />
As you should know already, once an element has an attribute, it is said to have a complex type. Therefore, before creating a schema tag for the attribute, you must first create a complex parent type. Then create a child tag. Instead of the element keyword, use attribute. Here is an example:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http:'www.w3.org/2001/XMLSchema">
<xs:element name="video">
<xs:complexType>
<xs:attribute name="title" type="xs:string">
</xs:complexType>
</xs:element>
</xs:schema>
In the same way, if a child element has an attribute, first create a complexType start-tag for it and close it. Inside this complex type, create a sequence start-tag and close it. Inside the new sequence tag, create an attribute tag for each attribute and specify its data type.
Options on Tags of an XML Schema
The Default Value of an Element or Attribute
By default, when creating an element or an attribute, you can give it any value you want. In fact, you create an element on one section of the document and give it a value, then create the same element in another section of the document but not give it a value. Here is an example:
<?xml version="1.0" encoding="utf-8" ?> <students> <student> <firstname>John</firstname> <lastname>Sandt</lastname> <gender>Male</gender> </student> <student> <firstname>Sherrie</firstname> <lastname>Springfield</lastname> <gender /> </student> </students>
If you have an element or an attribute that usually receive the same value, you can specify a default value for it. To do this, when creating the schema of the element or attribute, add a flag named default and assign the desired value to it. Here is an example:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http:'www.w3.org/2001/XMLSchema">
<xs:element name="students">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="student">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string" />
<xs:element name="lastname" type="xs:string" />
<xs:element name="gender" type="xs:string" default="Male" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
The Minimum Number of Occurrences of an Element
Consider the following XML document:
<?xml version="1.0" encoding="utf-8" ?> <products> <product> <number>283974</number> <dateacquired>2011-05-12</dateacquired> <name>Shirt with Epaullette</name> <size>14</size> <unitprice>59.95</unitprice> </product> <product> <number>485117</number> <dateacquired>2011-05-12</dateacquired> <name>Striped Pants</name> <size>Medium</size> <unitprice>78.50</unitprice> </product> </products>
Notice that the product element has two child nodes. When creating an XML document, you must want to require that the a certain element have at least a certain number of child elements. In that case, if the element has less than that number of child elements, the document would be in violation of the rule and therefore would be valid.
To specify that an element must have at least a certain number of child node, when creating its schema tag, add an attribute named minOccurs and assign the desired number to it. Here is an example:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http:'www.w3.org/2001/XMLSchema">
<xs:element name="products">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="4" name="product">
<xs:complexType>
<xs:sequence>
<xs:element name="number" type="xs:unsignedInt" />
<xs:element name="dateacquired" type="xs:date" />
<xs:element name="name" type="xs:string" />
<xs:element name="size" type="xs:string" />
<xs:element name="unitprice" type="xs:decimal" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
This code indicates that the products element must have at least 4 child nodes. Since the products element in the above XML document has only two child nodes, the element violates the rule and would produce an error.
The Maximum Number of Occurrences of an Element
When creating an XML document, by default, you can create as many elements as you want and each element can have as many child nodes as necessary. If you want, you can limit the number of child nodes an element can have. To do this, when creating the schema tag of the element, add an attribute named maxOccurs and assign the desired value to it. The value can be either an insigned integer or unbounded. This can be done as follows:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http:'www.w3.org/2001/XMLSchema">
<xs:element name="products">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="4" name="product">
<xs:complexType>
<xs:sequence>
<xs:element name="number" type="xs:unsignedInt" />
<xs:element name="dateacquired" type="xs:date" />
<xs:element name="name" type="xs:string" />
<xs:element name="size" type="xs:string" />
<xs:element name="unitprice" type="xs:decimal" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
In this case, the products element must not have more than 4 child nodes. In the XML document, if you create more child nodes for the element than the number specified in maxOccurs, the document would be violating the riule and would be considered invalid.
Since the minOccurs and the maxOccurs flags are not mutually exclusive, you can use them both on the same element. Here is an example:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http:'www.w3.org/2001/XMLSchema">
<xs:element name="products">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="6" name="product">
<xs:complexType>
<xs:sequence>
<xs:element name="number" type="xs:unsignedInt" />
<xs:element name="dateacquired" type="xs:date" />
<xs:element name="name" type="xs:string" />
<xs:element name="size" type="xs:string" />
<xs:element name="unitprice" type="xs:decimal" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Requiring an Attribute in an Element
Consider the following XML document:
<?xml version="1.0" encoding="utf-8" ?> <products> <product number="283974"> <dateacquired>2011-05-12</dateacquired> <name>Shirt with Epaullette</name> <unitprice>59.95</unitprice> </product> <product> <dateacquired>2011-05-12</dateacquired> <name>Striped Pants</name> <unitprice>78.50</unitprice> </product> </products>
Notice that the first product element has an attribute named number while the second product element does not have that attribute. When creating the schema of an element, you can ask that a certain attribute be required. To take care of this, when creating the schema of the attribute, add an attribute named use and assign a value named required to it. Here is an example:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http:'www.w3.org/2001/XMLSchema">
<xs:element name="products">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="product">
<xs:complexType>
<xs:sequence>
<xs:element name="dateacquired" type="xs:date" />
<xs:element name="name" type="xs:string" />
<xs:element minOccurs="0" name="size" type="xs:string" />
<xs:element name="unitprice" type="xs:decimal" />
</xs:sequence>
<xs:attribute name="number" type="xs:unsignedInt" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Once this flag is set, whenever the element of that attribute is created, that attribute must be added. Otherwise, the element would violate the rule.
Setting an Attribute as Optional
Once again, consider the above XML document. Notice that the first product element has an attribute named number but the second product element does not have that attribute. When creating the schema of an element, you can add a certain attribute to a certain element but omit that attribute for the same element in another section of the document. In this cas, the attribute is said to be optional. To indicate this, when creating the schema of the attribute, add the use attribute and assign a value named optional to it. Here is an example:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http:'www.w3.org/2001/XMLSchema">
<xs:element name="products">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="product">
<xs:complexType>
<xs:sequence>
<xs:element name="dateacquired" type="xs:date" />
<xs:element name="name" type="xs:string" />
<xs:element name="unitprice" type="xs:decimal" />
</xs:sequence>
<xs:attribute name="number" type="xs:unsignedInt" use="optional" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
The optional value is the default value of the use flag.
Preventing the Use of an Element or Attribute
If you want to prevent the use of an element from a certain element in your XML document, create its tag in the XML schema document. Add both the minOccurs and the maxOccurs attributes and set the value of each to 0. Here is an example:
<?xml version="1.0" encoding="utf-8"?> <xs:schema xmlns:xs="http:'www.w3.org/2001/XMLSchema"> <xs:element name="products"> <xs:complexType> <xs:sequence> <xs:element maxOccurs="unbounded" name="product"> <xs:complexType> <xs:sequence> <xs:element name="dateacquired" type="xs:date" /> <xs:element name="name" type="xs:string" /> <xs:element name="unitprice" type="xs:decimal" /> </xs:sequence> <xs:attribute name="number" type="xs:unsignedInt" use="optional" /> </xs:complexType> </xs:element> <xs:element name="closedcaption" minOccurs="0" maxOccurs="0" /> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
To prevent the use of a certain attribute, in the schema document, create its tag and add the use attribute. Assign a value as prohibited to itnamed onsider the above
Setting a Constant Value
Consider the following document:
<?xml version="1.0" encoding="utf-8" ?> <students> <student> <firstname>John</firstname> <lastname>Sandt</lastname> <gender>Male</gender> </student> <student> <firstname>Sherrie</firstname> <lastname>Springfield</lastname> <gender>Female</gender> </student> </students>
Notice that the first gender element has a value of Male and the second has a value of Female. We could have created one more gender element and give it any value. In a typical XML document, especially in the absence of a schema, you can give any value to an element. In some cases, you can specify a constant value that must always be used for an element. To do this, when creating the schema tag of the element, add an attribute named fixed and assign the desired value to it. Here is an example:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http:'www.w3.org/2001/XMLSchema">
<xs:element name="students">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="student">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string" />
<xs:element name="lastname" type="xs:string" />
<xs:element name="gender" type="xs:string" fixed="Female" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Once this is done, if a new element is created and it uses a value other than the one specified in the fixed flag, the document would be violating the rule.
The fixed flag can also be applied to an attribute, in which case you would require that an attribute always carry a certain value. In fact, you can add the use flag and specify whether the attribute must be required or it would be optional.