XMLSchema
XMLSchema
XMLSchema
What’s in a Schema?
A Schema is an XML document (a DTD is not)
<library xmlns=http://masters.cs.uchicago.edu/library>
<book id=“1234” available=“yes”>
<isbn>123456789 </isbn>
<title> Intro to XML</title> These must match. You can have
</book> other namespaces as well but must
declare targetNameSpace at least
</library>
<xs:schema targetNamespace=http://masters.cs.uchicago.edu/library
elementFormDefault=“qualified” attributeFormDefault=“unqualified”
xmlns:lib=http://masters.cs.uchicago.edu/library>
xmlns:xs=http://www.w3.org/2001/XMLSchema>
… These just introduce
</xs:schema> namespaces, as we did
before
More on previous example
It is very important to realize that there are two
things going on here:
Introduction of whatever namespaces we want and
their associated prefixes. This is easy
<xs:schema ../> also can specify behavior for entire document using
elementFormDefault=“qualified | unqualified”
attributeFormDefault=“qualified | unqualified”
<xs:simpleType name="unitsType">
<xs:restriction base="xs:string">
<xs:enumeration value="K"/>
<xs:enumeration value="g_per_cm3"/>
<xs:enumeration value="W_per_cm-K"/>
<xs:enumeration value="kW_per_m"/>
</xs:restriction>
</xs:simpleType>
Exercise 1
Suggest a good solution for describing the units
attribute (or element if you prefer), keeping in
mind the following:
Each physical property has different combinations of
units in general
There are typical ways of expressing the values (e.g.
grams vs Mgrams), but we might not want to prohibit
unusual choices
We would like robust validation
We might want to compute new properties from
combinations of existing properties
We want something not too difficult to parse
A Solution
My initial solution is particularly bad for pretty
obvious reasons
Example:(a+b)2
<msup> <apply>
<mfenced> <power/>
<mi>a</mi> <apply>
<mo>+</mo> <plus/>
<ci>a</ci>
<mi>b</mi>
<ci>b</ci>
</mfenced>
</apply>
<mn>2</mn> <cn>2</cn>
</msup> </apply>
<mml:mrow>
<mml:msup> <mml:mi>x</mml:mi><mml:mn>2</mml:mn></mml:msup>
<mml:mo>+</mml:mo>
<mml:mrow>
<mml:mn>4</mml:mn><mml:mo>+</mml:mo><mml:mi>x</mml:mi>
</mml:mrow>
<mml:mo>+</mml:mo>
<mml:mn>4</mml:mn>
</mml:mrow>
Where can the same name be used, and where will there be a
name conflict?
Type definitions are placed in one symbol space.
Element declarations are placed in a second symbol space
Attribute declarations are placed in a third symbol space.
Illegal
Same name and same Symbol Space but different type
Legal
Same name and same Symbol Space and same type
<xsd:element name="foo">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="bar" type="xsd:string"/>
...
<xsd:element name="bar" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType
</xsd:element>
Is this legal or illegal?
<xsd:element name="foo">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="bar" type="xsd:string"/>
...
<xsd:element name="bar" type="xsd:integer"/>
</xsd:sequence>
</xsd:complexType
</xsd:element>
Title
<xsd:element name="BookOnCars"> anonymous
<xsd:complexType> symbol space
<xsd:sequence>
<xsd:element name="Chapter">
Chapter
<xsd:complexType>
<xsd:sequence> Title
<xsd:element name="Title" type="xsd:string"/>
<xsd:element name="Section">
<xsd:complexType> anonymous
<xsd:sequence> symbol space
<xsd:element name="Title" type="xsd:string"/>
</xsd:sequence>
Title
</xsd:complexType>
</xsd:element> Section
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="Title" type="xsd:string"/> anonymous
</xsd:sequence> symbol space
</xsd:complexType>
</xsd:element>
Title
<xsd:complexType name="Title">
<xsd:sequence>
<xsd:element name="CarManufacturer" type="xsd:string"/>
<xsd:element name="Year" type="year"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="Title" type="xsd:string"/> Title
<xsd:attribute name="Title" type="xsd:string"/> symbol space
CarManufacturer
Year
Global/Local Elements and
Namespaces
You can define the element globally and use a reference to it instead.
<xs:element name="rooms">
<xs:complexType>
<xs:sequence>
<xs:element ref="room"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="room">
…
</xs:element>
Rooms Schema using References
<xs:element name="features">
<xs:complexType>
<xs:sequence>
<xs:element name="feature" type="xs:string” maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
Types
Also, recall that named types themselves can be defined independently of any
element and used to create elements.
<xsd:element name="Robot">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="Sensor_List" minOccurs="0"/>
<xsd:element ref="Specification_List" minOccurs="0"/>
<xsd:element ref="Note" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
OR
<xsd:element name="Robot” type=“RoboType”>
<xsd:complexType name="RoboType” >
<xsd:sequence>
<xsd:element ref="Sensor_List" minOccurs="0"/>
<xsd:element ref="Specification_List" minOccurs="0"/>
<xsd:element ref="Note" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
Types vs. Refs vs. Anonymous
Questions to the class
Type hierarchy:
http://www.w3.org/TR/xmlschema-2/#built-in-datatypes
Simple Type
<xs:simpleType>
<xsd:simpleType name=“typeName”>
<xsd:restriction base=“builtIn_or_userDef”>
<facet1 value=“Value”/>
<facet1 value=“Value”/>
<facet1 value=“Value”/>
<!-- etc. -->
</xsd:restriction>
</xsd:simpleType>
List and Union syntax
<xsd:simpleType name=“typeName”>
<xsd:list itemType=“simpleType”>
</xsd:simpleType>
<xsd:simpleType name=“typeName”>
<xsd:union memberTypes=“simpleType1 simpleType2 ...”>
</xsd:simpleType>
Restriction examples
<!– restricting upper and lower value of int -->
<xs:simpleType name=“myInteger”>
<xs:restriction base=“xs:integer”>
<xs:minInclusive value=“-2”/>
<xs:maxInclusive value=“5/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="testList">
<xs:list itemType="xs:int"/>
</xs:simpleType>
<xs:simpleType name="unionList">
<xs:list itemType="testUnion"/>
</xs:simpleType>
<xs:simpleType name=“fixedUnionList”>
<xs:restriction base=“unionList”>
<xs:maxLength=3/>
</xs:restriction>
</xs:simpleType>
Examples
<!– example two facets together-->
<xs:simpleType name="myString">
<xs:restriction base="xs:string">
<xs:length value="3"/>
<xs:whiteSpace value="collapse"/>
</xs:restriction>
</xs:simpleType>
2. Create a new simple type that is a list of 10-20 elements of each member of which can be either an
xs:int greater than zero or an xs:date
<xsd:simpleType name=“typeName”>
<xsd:list itemType=“simpleType”>
</xsd:simpleType>
<xsd:simpleType name=“typeName”>
<xsd:union memberTypes=“simpleType1 simpleType2 ...”>
</xsd:simpleType>
Answer 1
<xs:simpleType name="foo1">
<xs:restriction base="xs:token">
<xs:maxLength value="10"> </xs:maxLength>
<xs:minLength value="9"> </xs:minLength>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="foo2">
<xs:list itemType="foo1"> </xs:list>
</xs:simpleType>
<xs:simpleType name="foo3">
<xs:restriction base="foo2">
<xs:length value="3"> </xs:length>
</xs:restriction>
</xs:simpleType>
Answer 2
<xs:simpleType name="posInt">
<xs:restriction base="xs:integer">
<xs:minInclusive value="1"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="listofUnions">
<xs:list>
<xs:simpleType>
<xs:union memberTypes="posInt xs:date"/>
</xs:simpleType>
</xs:list>
</xs:simpleType>
<xs:simpleType name="restrictedListofUnions">
<xs:restriction base="listofUnions">
<xs:minLength value="10"/>
<xs:maxLength value="20"/>
</xs:restriction>
</xs:simpleType>
Complex Types
Complex vs. Simple types
Recall that these are fundamentally different
<xs:complexType name=“tokenWithLang”>
<xs:simpleContent>
<xs:extension base=“xs:token”>
<xs:attribute ref=“lang”/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name=“title”>
<xs:complexType>
<xs:simpleContent>
<xs:extension base=“tokenWithLang”>
<xs:attribute name=“note” type=“xs:token”/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
Derivation by restriction
Can restrict text node in regular way
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="tokenWIthLangAndNote">
<xs:simpleContent>
<xs:extension base="xs:token">
<xs:attribute name="lang" type="xs:language"/>
<xs:attribute name="note" type="xs:token"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name="title">
<xs:complexType>
<xs:simpleContent>
<xs:restriction base="tokenWIthLangAndNote">
<xs:maxLength value="8"/>
</xs:restriction>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:schema>
Derivation by restriction
Can remove an attribute using prohibited
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="tokenWIthLangAndNote">
<xs:simpleContent>
<xs:extension base="xs:token">
<xs:attribute name="lang" type="xs:language"/>
<xs:attribute name="note" type="xs:token"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name="title">
<xs:complexType>
<xs:simpleContent>
<xs:restriction base="tokenWIthLangAndNote">
<xs:attribute name=“note” use=“prohibited”>
</xs:restriction>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:schema>
Derivation by restriction
Can restrict the value of attributes
<xs:element name="title">
<xs:complexType>
<xs:simpleContent>
<xs:restriction base="tokenWIthLangAndNote">
<xs:attribute name=“lang”>
<xs:simpleType>
<xs:restriction base=“xs:language”>
<xs:enumeration value=“en”/>
<xs:enumeration value=“es”/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:restriction>
</xs:simpleContent>
</xs:complexType>
</xs:element>
Derivation of Complex Content by extension
<xs:element name="author">
<xs:complexType>
<xs:complexContent>
<xs:extension base="basePerson">
<xs:sequence>
<xs:element ref="dead" minOccurs="0"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
</xs:schema>
Restricting complex content models
<xs:complexType name="person">
<xs:sequence>
<xs:element ref="name"/>
<xs:element ref="born"/>
<xs:element ref="dead" minOccurs="0"/>
<xs:element ref=“qualification” minOccurs=“0”/>
</xs:sequence>
<xs:attribute ref="id"/>
</xs:complexType>
<xs:complexType name="bookListType">
<xs:sequence>
<xs:element name="book" type="bookType"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="authorListType">
<xs:sequence>
<xs:element name="author" type="authorType" minOccurs="1" maxOccurs="unbounded"/
</xs:sequence>
</xs:complexType>
<xs:complexType name="authorType">
<xs:sequence>
<xs:element name="last" type="xs:string"/>
<xs:element name="first" type="xs:string"/>
</xs:sequence>
<xs:attribute name="identifier" type="xs:ID" use="required"/>
</xs:complexType>
<xs:complexType name="bookType">
<xs:sequence>
<xs:element name="isbn" type="xs:token"/>
<xs:element name="title" type="xs:string"/>
<xs:element name="author-ref">
<xs:complexType>
<xs:attribute name="ref" type="xs:IDREF" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
<?xml version="1.0" encoding="UTF-8"?>
<library xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="file:/Users/siegela/Desktop/cspp51038/examples/IDExample
<authorList>
<author identifier="ID000">
<last>last0</last>
<first>first0</first>
</author>
<author identifier="ID001">
<last>last0</last>
<first>first0</first>
</author>
</authorList>
<bookList>
<book>
<isbn>isbn0</isbn>
<title>title0</title>
<author-ref ref="ID000"/>
</book>
</bookList>
</library>
Key/keyref
Much more flexible and arguably sensible
than ID’s
</xs:element>
</xs:sequence> “each employee element of workPlan
</xs:complexType> is unique based on its social field
<xs:unique name="social_key">
<xs:selector xpath="employee"/>
<xs:field xpath="social"/>
</xs:unique>
</xs:element>
</xs:schema>
<?xml version="1.0" encoding="UTF-8"?>
<workPlan xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="file:workPlan.xsd">
<assignment>
<assignee>assignee0</assignee>
<taskName>taskName0</taskName>
<length>2147483647</length>
</assignment>
<employee>
<social>social0</social>
<last>last0</last>
<first>first0</first>
</employee>
<employee> This won’t validate!
<social>social0</social>
<last>last0</last>
<first>first0</first>
</employee>
</workPlan>
Adding keyref
<xs:unique name="social_key">
<xs:selector xpath="employee"/>
<xs:field xpath="social"/>
</xs:unique>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:whitespace value="replace"/>
</xs:restriction>
</xs:simpleType>
Type Extensions
A third way of creating a complex type is to extend another
complex type (like OO inheritance)
<xs:complexType name="PersonInfoType">
<xs:complexContent>
<xs:extension base="PersonNameType">
<xs:sequence>
<xs:element name="Address" type="xs:string"/>
<xs:element name="City" type="xs:string"/>
<xs:element name="Country" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
Type Extensions (use)
<ADDRESS>
<NAME> Martin Sheen </NAME>
…
<ZIP> 4145 </ZIP>
</ADDRESS>