I have googled this question, but I do not understand clearly what is an XML schema and DTD (document type definition), and why the XML schema is more powerful compared to DTD.
Any guidance would be highly appreciated.
From the Differences Between DTDs and Schema section of the Converting a DTD into a Schema article:
The critical difference between DTDs and XML Schema is that XML Schema utilize an XML-based syntax, whereas DTDs have a unique syntax held over from SGML DTDs. Although DTDs are often criticized because of this need to learn a new syntax, the syntax itself is quite terse. The opposite is true for XML Schema, which are verbose, but also make use of tags and XML so that authors of XML should find the syntax of XML Schema less intimidating.
The goal of DTDs was to retain a level of compatibility with SGML for applications that might want to convert SGML DTDs into XML DTDs. However, in keeping with one of the goals of XML, "terseness in XML markup is of minimal importance," there is no real concern with keeping the syntax brief.
[...]
So what are some of the other differences which might be especially important when we are converting a DTD? Let's take a look.
Typing
The most significant difference between DTDs and XML Schema is the capability to create and use datatypes in Schema in conjunction with element and attribute declarations. In fact, it's such an important difference that one half of the XML Schema Recommendation is devoted to datatyping and XML Schema. We cover datatypes in detail in Part III of this book, "XML Schema Datatypes."
[...]
Occurrence Constraints
Another area where DTDs and Schema differ significantly is with occurrence constraints. If you recall from our previous examples in Chapter 2, "Schema Structure" (or your own work with DTDs), there are three symbols that you can use to limit the number of occurrences of an element: *, + and ?.
[...]
Enumerations
So, let's say we had a element, and we wanted to be able to define a size attribute for the shirt, which allowed users to choose a size: small, medium, or large. Our DTD would look like this:
<!ELEMENT item (shirt)> <!ELEMENT shirt (#PCDATA)> <!ATTLIST shirt size_value (small | medium | large)>
[...]
But what if we wanted
size
to be an element? We can't do that with a DTD. DTDs do not provide for enumerations in an element's text content. However, because of datatypes with Schema, when we declared the enumeration in the preceding example, we actually created asimpleType
calledsize_values
which we can now use with an element:<xs:element name="size" type="size_value">
[...]
Differences between an XML Schema Definition (XSD) and Document Type Definition (DTD) include:
Not all these bullet points are 100% accurate, but you get the gist.
On the other hand:
As many people have mentioned before, XML Schema utilize an XML-based syntax and DTDs have a unique syntax. DTD doesn't support datatypes, which does matter.
Lets see a very simple example in which university has multiple students and each student has two elements "name" and "year". Please note that I have uses "// --> " in my code just for comments.
Now I will write this example both in DTD and in XSD.
DTD
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE university[ // --> university as root element
<!ELEMENT university (student*)> // --> university has * = Multiple students
<!ELEMENT student (name,year)> // --> Student has elements name and year
<!ELEMENT name (#PCDATA)> // --> name as Parsed character data
<!ELEMENT year (#PCDATA)> // --> year as Parsed character data
]>
<university>
<student>
<name>
John Niel //---> I can also use an Integer,not good
</name>
<year>
2000 //---> I can also use a string,not good
</year>
</student>
</university>
XML Schema Definition (XSD)
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:complexType name ="uniType"> //--> complex datatype uniType
<xsd:sequence>
<xsd:element ref="student" maxOccurs="unbounded"/> //--> has unbounded no.of students
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="stuType"> //--> complex datatype stuType
<xsd:sequence>
<xsd:element ref="name"/> //--> has element name
<xsd:element ref="year"/> //--> has element year
</xsd:sequence>
</xsd:complexType>
<xsd:element name="university" type="uniType"/> //--> university of type UniType
<xsd:element name="student" type="stuType"/> //--> student of type stuType
<xsd:element name="name" type="xsd:string"/> //--> name of datatype string
<xsd:element name="year" type="xsd:integer"/> //--> year of datatype integer
</xsd:schema>
<?xml version="1.0" encoding="UTF-8"?>
<university>
<student>
<name>
John Niel
</name>
<year>
2000 //--> only an Integer value is allowed
</year>
</student>
</university>
both specify elements, attributes, nesting, ordering, #occurences
XSD also has data types, (typed) pointers, namespaces, keys and more.... unlike DTD
Moreover though XSD is little verbose its syntax is extension of XML, making it convenient to learn fast.
One difference is that in a DTD the content model of an element is completely determined by its name, independently of where it appears in the document:
Assuming you want to have
person
elementname
name
itself has child elements first
and last
. Like this
<person>
<name>
<first></first>
<last></last>
</name>
</person>
If a city
element in the same document also needs to have a child element 'name' the DTD requires that this 'name' element must have child elements first
and last
as well. Despite the fact that city.name
does not require first
and last
as children.
In contrast, XML Schema allows you to declare child element types locally; you could declare the name
child elements for both person
and city
separately. Thus giving them their proper content models in those contexts.
The other major difference is support for namespaces. Since DTDs are part of the original XML specification (and inherited from SGML), they are not namespace-aware at all because XML namespaces were specified later. You can use DTDs in combination with namespaces, but it requires some contortions, like being forced to define the prefixes in the DTD and using only those prefixes, instead of being able to use arbitrary prefixes.
To me, other differences are mostly superficial. Datatype support could easily be added to DTDs, and syntax is just syntax. (I, for one, find the XML Schema syntax horrible and would never want to hand-maintain an XML Schema, which I wouldn't say about DTDs or RELAX NG schemas; if I need an XML Schema for some reason, I usually write a RELAX NG one and convert it with trang
.)
Similarities:
DTDs and Schemas both perform the same basic functions:
Differences:
DTDs are better for text-intensive applications, while schemas have several advantages for data-intensive workflows.
Schemas are written in XML and thusly follow the same rules, while DTDs are written in a completely different language.
Examples:
DTD:
<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT employees (Efirstname, Elastname, Etitle, Ephone, Eemail)>
<!ELEMENT Efirstname (#PCDATA)>
<!ELEMENT Elastname (#PCDATA)>
<!ELEMENT Etitle (#PCDATA)>
<!ELEMENT Ephone (#PCDATA)>
<!ELEMENT Eemail (#PCDATA)>
XSD:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:od="urn:schemas-microsoft-com:officedata">
<xsd:element name="dataroot">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="employees" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="generated" type="xsd:dateTime"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="employees">
<xsd:annotation>
<xsd:appinfo>
<od:index index-name="PrimaryKey" index-key="Employeeid " primary="yes"
unique="yes" clustered="no"/>
<od:index index-name="Employeeid" index-key="Employeeid " primary="no" unique="no"
clustered="no"/>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Elastname" minOccurs="0" od:jetType="text"
od:sqlSType="nvarchar">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="50"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="Etitle" minOccurs="0" od:jetType="text" od:sqlSType="nvarchar">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="50"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="Ephone" minOccurs="0" od:jetType="text"
od:sqlSType="nvarchar">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="50"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="Eemail" minOccurs="0" od:jetType="text"
od:sqlSType="nvarchar">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="50"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="Ephoto" minOccurs="0" od:jetType="text"
od:sqlSType="nvarchar">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="50"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
The purpose of a DTD is to define the structure of an XML document. It defines the structure with a list of legal elements:
<!ATTLIST contact type CDATA #IMPLIED>
<!ELEMENT address1 ( #PCDATA)>
<!ELEMENT city ( #PCDATA)>
<!ELEMENT state ( #PCDATA)>
<!ELEMENT zip ( #PCDATA)>
XML Schema enables schema authors to specify that element quantity’s data must
be numeric or, even more specifically, an integer. In the following example I used string
:
<xs:element name="note">
<xs:complexType>
<xs:sequence>
<xs:element name="address1" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="state" type="xs:string"/>
<xs:element name="zip" type="xs:string"/>
</xs:sequence>
</xs:complexType>
DTD can have only two types of data, the CDATA and the PCDATA. But in a schema you can use all the primitive data type that you use in the programming language and you have the flexibility of defining your own custom data types.
The developer building a schema can create custom data types based on the core data types and by using different operators and modifiers.
When XML first came out, we were told it would solve all our problems: XML will be user-friendly, infinitely extensible, avoid strong-typing, and not require any programming skills. I learnt about DTD's and wrote my own XML parser. 15+ years later, I see that most XML is not user-friendly, and not very extensible (depending on its usage). As soon as some clever clogs hooked up XML to a database I knew that data types were all but inevitable. And, you should see the XSLT (transformation file) I had to work on the other day. If that isn't programming, I don't know what is! Nowadays it's not unusual to see all kinds of problems relating to XML data or interfaces gone bad. I love XML but, it has strayed far from its original altruistic starting point.
The short answer? DTD's have been deprecated in favor of XSD's because an XSD lets you define an XML structure with more precision.