1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

163
1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML

Transcript of 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

Page 1: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

1Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

DEEL II XML

Page 2: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

2Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Table of Contents

1. Semistructured Data2. Introduction to XML3. Querying XML4. XPath5. XQuery6. Typing in XQuery7. Document Type Definitions8. XML Schema9. Light XQuery 10. XSLT

Page 3: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

3Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

References

I. XML

[1] www.w3.org/TR/xmlschema-0

[2] www.w3.org/TR/xmlschema-1

[3] www.w3.org/TR/xpath

[4] P.M. Lewis, A. Bernstein, M. Kifer, Databases and Transaction Processing, Addison Wesley, Chapter 17, 2002

[5] D. Chamberlin, XQuery, a query language for XML, Web, June 2003

[6] www.w3.org/TR/xquery

[7] www.w3.org/XML/Query

Page 4: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

4Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

References

[8] www.w3.org/TR/xslt20

[9] Draper et al, XQuery 1.0 and XPath 2.0 Formal Semantics, www.w3.org/TR/xquery-semantics/, 2003

[10] M. Brundage, XQuery, Add. Wesley, 2004

[11] J. McGovern, P. Bothner, K. Cagle, J. Linn, V.

Nagarajan, XQuery, Sams Publ., 2004

[12] H. Katz, XQuery from the Experts, Add. Wesley, 2004

Page 5: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

5Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

1. Semistructured Data [4]

• Web data for human consumption– HTML (Cfr. next slide)– Self describing: attribute names are included

• but not explicitly separated from data values• Web data for machine consumption

– Characteristics of Semistructured Data:• object-like• schemaless• self-describing

– XML • (optional) structure descr.: DTD, XML Schema

Page 6: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

6Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<html> <head><Title>Student List</Title></head> <body> <h1>ListName: Students</h1> <dl> <dt>Name: Jan Vijs <dd>Id: 11 <dd>Address: <ul> <li>Number: 123 <li>Street: Turnstreet </ul> <dt>Name: Jan De Moor <dd>Id: 66 <dd>Address: <ul> <li>Number: 4 <li>Street: Hole Rd </ul> </dl> </body></html>

HTML-document

Page 7: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

7Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

2. Introduction to XML [4]

• Why is XML important?– simple open non-proprietary widely accepted data

exchange format• XML is like HTML but

– no fixed set of tags• X = “extensible”

– no fixed semantics (c.q. representation) of tags• representation determined by separate ‘stylesheet’• semantics determined by application

– no fixed structure• user-defined schemas

Page 8: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

8Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<?xml version ="1.0"?><PersonList Type="Student" Date="2004-12-12"> <Title Value="Student List"/> <Contents> <Person> <Name>Jan Vijs</Name> <Id>11</Id> <Address> <Number>123</Number> <Street>Turnstreet</Street> </Address> </Person> <Person> <Id>66</Id> <Address> <Number>4</Number> <Street>Hole Rd</Street> </Address> </Person> </Contents></PersonList>

XML-document – Running example 1

Page 9: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

9Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• Global structure– First line is mandatory;– Tags are chosen by author;– Opening tag must have a matching closing tag;

<a><b></b><c></c></a>

– Only one root element PersonList;– <a> … </a>; a is the name of the element, content,

child, descendant, parent, ancestor, sibling;– <PersonList Type=“Student”> Type is name of the

attribute of element PersonList; the value of the attribute is “Student” ; all attribute values must be quoted;

Page 10: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

10Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

– empty elements: <Title Value=“Student List”> </Title> <Title Value=“Student List”/>

– processing instruction: <? . . . ?>– comment: <!–- here we go -->– mixed data-text:

<Address>

Jan lives in <Street> Q Street </Street> number <Number> 123 </Number>

</Address>

– elements are ordered:<Address> <Address> <Number> 123 </Number> <Street> Q Street </Street>

<Street> Q Street </Street> <Number> 123 </Number></Address> </Address>

are different– weak facilities for constraints

Page 11: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

11Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

XML Attributes

• An element can have any number of attributes;• the order of the attributes does not matter;• an attribute can only occur once within an element;• attribute values can only be strings;• the following have the same semantics (except for the ordering of <b>

and <c>):

<a b=“2” c=“Jan” />

<a> <b> 2 </b> <c> Jan </c> </a>

Page 12: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

12Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Well-formedness

• We call an XML-document well-formed iff– it has one root element;– elements are properly nested;– any attribute can only occur once in a given opening

tag and its value must be quoted;

Page 13: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

13Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Types of nodes:• document,

• element,

• text,

• attribute

Root

Students

CrsTaken

Student Student

Name

First Last

CrsTakenStudId

Semester CrsCodeSemester

CrsCode

Root

Students

Semester

siblings are ordered

<Students> <Student StudId=“dr”> <Name> <First> John </First> <Last> Doe </Last> </Name> U4 <CrsTaken Semester=“…” CrsCode=“…”/> <CrsTaken Semester=“…” CrsCode=“…”/> </Student> <Student> … </Student> </Students>

Data Model

“dr”

“John” “Doe”

“U4”

Page 14: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

14Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• A value is an ordered sequence of zero or more items;• An item is a node or an atomic value;• There are four kinds of nodes:

• Document Node• Element Node• Attribute Node• Text Node

• Children are element or text nodes (no attribute nodes)• Examples of values

• 47• <goldfish/>• (1, 2, 3)• (47, <goldfish/>, "Hello")• ()• An XML document• An attribute standing by itself

Page 15: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

15Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• There is no distinction between an item and a sequence of length one;• There are no nested sequences;• There is no null value;• A sequence can be empty;• Sequences can contain heterogeneous values;• All sequences are ordered;• Nodes have identity (atomic values don't);• Element and attribute nodes have a type annotation; (not considered here)

• May be a complex type such as PurchaseOrder; (not considered here)

• Type may be unknown ("anyType");• Each node has a typed value; (not considered here)

• There is a document order among nodes;• Ordering among documents and constructed nodes is

implementation-defined but stable;

Page 16: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

16Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• Cfr. C++

• Building vocabularies to prevent naming conflicts;• uniform use of tag-names;• general form of a tag:

<URI:local-name> or <URL:local-name> in principle nothing to do with Internet.

• use different URIs(URLs) for different domains;“http://www.acmeinc.com/jp#students” for students

“http://www.acmeinc.com/jp#toys” for toys

• synonyms for URIs (URLs) can be declared;called namespaces

• default namespace;

Namespaces

Page 17: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

17Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<item xmlns=“http://www.acmeinc.com/jp#supplies” xmlns:toy=“http://www.acmeinc.com/jp#toys”> <name>backpack</name> <feature> <toy:item> <toy:name>cyberpet</toy:name> </toy:item> </feature> <item xmlns=“http://www.acmeinc.com/jp#supplies2” xmlns:toy=“http://www.acmeinc.com/jp#toys2”> <name>notebook</name> <toy:name>sticker</toy:name> </item></item>

• the default namespace is declared by the attribute xmlns• the other namespaces are declared by xmlns:<synonym>• the outermost <item>, the first <name> and <feature> belong to default namespace

“http://www.acmeinc.com/jp#supplies”• <toy:item> and the first <toy:name> belong to the namespace “http://www.acmeinc.com/jp#toys”• the innermost <item> and the second <name> belong to the default namespace

“http://www.acmeinc.com/jp#supplies2”• the second <toy:name> belongs to the namespace “http://www.acmeinc.com/jp#toys2”

Page 18: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

18Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<?xml version="1.0"?><adm:Report adm:Date="2004-12-12"> <adm:Students> <adm:Student adm:StudId=“ST11"> <adm:Name> <adm:First>Jan</adm:First> <adm:Last>Vijs</adm:Last> </adm:Name> <adm:Status>U2</adm:Status> <adm:CrsTaken adm:CrsCode="CS308" adm:Semester="F2003"/> <adm:CrsTaken adm:CrsCode="MAT123" adm:Semester="F2003"/> </adm:Student> <adm:Student adm:StudId=“ST66"> <adm:Name> <adm:First>Jan</adm:First> <adm:Last>De Moor</adm:Last> </adm:Name> <adm:Status>U3</adm:Status> <adm:CrsTaken adm:CrsCode="CS308" adm:Semester="S2002"/> <adm:CrsTaken adm:CrsCode="MAT123" adm:Semester="F2003"/> </adm:Student> <adm:Student adm:StudId=“ST98"> <adm:Name> <adm:First>Bart</adm:First> <adm:Last>Simpson</adm:Last> </adm:Name> <adm:Status>U4</adm:Status> <adm:CrsTaken adm:CrsCode="CS308" adm:Semester="S2002"/> </adm:Student> </adm:Students>

Running example 2

Page 19: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

19Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<adm:Classes>

<adm:Class>

<adm:CrsCode>CS308</adm:CrsCode>

<adm:Semester>S2002</adm:Semester>

<adm:ClassRoster adm:Members=“ST66 ST98"/>

</adm:Class>

<adm:Class>

<adm:CrsCode>CS308</adm:CrsCode>

<adm:Semester>F2003</adm:Semester>

<adm:ClassRoster adm:Members=“ST11"/>

</adm:Class>

<adm:Class>

<adm:CrsCode>MAT123</adm:CrsCode>

<adm:Semester>F2003</adm:Semester>

<adm:ClassRoster adm:Members=“ST11 ST66"/>

</adm:Class>

</adm:Classes>

<adm:Courses>

<adm:Course adm:CrsCode="CS308">

<adm:CrsName>Databases</adm:CrsName>

</adm:Course>

<adm:Course adm:CrsCode="MAT123">

<adm:CrsName>Algebra</adm:CrsName>

</adm:Course>

</adm:Courses>

</adm:Report>

Page 20: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

20Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

3. Querying XML

• Why query XML-documents?– special XML databases– major DBMSs “speak” XML;

• Does the world need a new query language?• Most of the world's business data is stored in relational

databases;• The relational language SQL is mature and well-

established;• Can SQL be adapted to query XML data?

– Leverage existing software– Leverage existing user skills

Page 21: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

21Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• How is XML data different from relational data?

• Relational data is "flat”: rows and columns;• XML data is nested: and its depth may be

irregular and unpredictable;

• Relations can represent hierarchic data by foreign keys or by structured datatypes;

• In XML it is natural to search for objects at unknown levels of the hierarchy: "Find all the red things“;

Page 22: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

22Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• Relational data is uniform and repetitive; All bank accounts are similar in structure; Metadata can be factored out to a system catalog;• XML data is highly variable; Every web page is different; Each XML object needs to be self-describing; Metadata is distributed throughout the document; Queries may access metadata as well as data:

"Find elements whose name is the same as their content“: //*[name(.) =string(.)]

Page 23: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

23Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• Relational queries return uniform sets of rows;• The results of an XML query may have mixed

types and complex structures; "Red things": a flag, a cherry, a stopsign, ... Elements can be mixed with atomic values; XML queries need to be able to perform structural transformations; Example: invert a hierarchy;

Page 24: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

24Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• The rows of a relation are unordered; Any desired output ordering must be derived

from values;• The elements in an XML document are ordered; Implications for query:

• Preserve input order in query results• Specify an output ordering at multiple levels;

"Find the fifth step“; "Find all the tools used before the hammer“;

Page 25: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

25Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• Relational data is "dense“; Every row has a value in every column; A "null" value is needed for missing or

inapplicable data;• XML data can be "sparse“; Missing or inapplicable elements can be "empty"

or "not there“; This gives XML a degree of freedom not present in

relational databases;

Page 26: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

26Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Unabbreviated syntax

A location path transforms a document tree and one of its nodes as a context node to a sequence of distinct nodes indocument order.• child::a selects the element children with name a of the context node• child::* selects all element children of the context node• child::text() selects all text children of the context node• child::node() selects all the (element or text) children of the context node• attribute::a selects the attribute with name a of the context node• attribute::* selects all the attributes of the context node• descendant::a selects the element descendants with name a of the context node• descendant-or-self::a selects the element descendants with name a of the context node and, if the context node has name a, the context node as well• ancestor::a selects all ancestors with name a of the context node• ancestor-or-self::a selects the ancestors with name a of the context node and, if the context node is an element with name a, the context node as well• self::a selects the context node if it is has the name a, and otherwise selects nothing• child::chapter/descendant::a selects the element descendants with name a of the element children with name chapter of the context node• child::*/child::a selects all element grandchildren with name a of the context node• / selects the document root

4 XPath [3,5]

Page 27: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

27Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• /descendant::a selects all the elements with name a in the same document as the context node• /descendant::a/child::b selects all the elements with name b that have a parent with name a and that are in the same document as the context node• child::a[position()=1] selects the first child with name a of the context node• child::a[position()=last()] selects the last child with name a of the context node• child::a[position()=last()-1] selects the last but one child with name a of the context node• child::a[position()>1] selects all the children with name a of the context node other than the first child with name a of the context node• following-sibling::chapter[position()=1] selects the next chapter sibling of the context node• preceding-sibling::chapter[position()=1] selects the prev. chapter sibling of the context node• /descendant::figure[position()=42] selects the forty-second element with name figure in the document• child::a[attribute::type=“warning”] selects all the children with name a of the context node that have an attribute with name type and value “warning” • child::a[attribute::type=“warning”][position()=5] selects the fifth child with name a of the context node that has an attribute with name type and value “warning” • child::a[position()=5][attribute::type="warning”] selects the fifth child with name a of the context node if that child has an attribute with name type and value “warning” • child::chapter[child::title] selects the chapter children of the context node that have one or more children with name title• child::*[self::chapter or self::appendix] selects the chapter and appendix children of the context node• child::*[self::chapter or self::appendix][position()=last()] selects the last chapter or appendix

Page 28: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

28Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

General form of a location path:

• relative lp : step1 / step2 / … / stepn (n > 0)

child::*/child::name

Each step in turn selects a sequence of nodes relative to a context node. An initial sequence of steps is composed together with a following step as follows: the initial sequence of steps selects a sequence of nodes relative to a context node. Each node in that sequence is used as a context node for the following step. The sequences of nodes identified by that step are unioned together. The sequence of nodes identified by the composition of the steps is this union, ordered in document order, without duplicates.

The example selects the union of all name children of children of the context node.

• absolute lp : / step1 / step2 / … / stepn (n 0) /child::*/child::name

The initial / selects the root node of the document containing the context node.Then apply step1 / step2 / … / stepn

Page 29: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

29Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

General form of step :

axis :: node-test [predicate1] … [predicaten] (n0)

child::name[attribute::type=“warning”][position()=5]

The node-sequence selected by the step is the node-sequence that results from generating an initial node-sequence from the axis, filtering it by the node-test, and then filtering that node-sequence by each of the predicates in turn.

• the child axis contains the element and text children of the context node;

• the descendant axis contains the element and text descendants of the context node; • the parent axis contains the parent of the context node;

• the ancestor axis contains the ancestors of the context node;

• if the context node is an element or text node the following-sibling axis contains all the following element or text siblings of the context node; if the context node is an attribute node, the following-sibling axis is empty;

• if the context node is an element or text node the preceding-sibling axis contains all the preceding element or text siblings of the context node; if the context node is an attribute node, the preceding-sibling axis is empty;

Page 30: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

30Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• the following axis contains all element or text nodes in the same document as the context node that are after the context node in document order (preorder), excluding any descendants;

• the preceding axis contains all element or text nodes in the same document as the context node that are before the context node in document order, excluding any ancestors;

• the attribute axis contains the attribute children of the context node;

• the self axis contains just the context node itself;

• the descendant-or-self axis contains the context node and the descendants of the context node;

• the ancestor-or-self axis contains the context node and the ancestors of the context node;

Remark that the ancestor, descendant, following, preceding and self axis partition the element nodes of a document.

parent::*/parent::*/child::*/following-sibling::*/preceding-sibling::*/following::*/descendant::*/ancester::*/preceding::*

Page 31: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

31Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Node-test has the form:• label : filters the nodes with that label• * : filters all element nodes• node() : filters all nodes• text() : filters the text nodes

Predicate has (until now) the form: [position()=i]The ancestor, ancestor-or-self, preceding, and preceding-sibling axes are reverse axes; all other axes are forward axes. The proximity position of a node of a node-sequence with respect to an axis is defined to be the position of the node in the node-sequence ordered in document order if the axis is a forward axis and ordered in reverse document order if the axis is a reverse axis. The first position is 1. [position()=i] filters those nodes whose proximity position is equal to i.parent::*/parent::*/child::*/following-sibling::*/preceding-sibling::*[position()=1]/following::*/descendant::*/ ancestor::*[position()=1]/preceding::*

Page 32: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

32Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Abbreviated Syntax in red

More used than the unabbreviated syntax.

• child:: is omitted child::name name

• attribute:: is abbreviated to @ attribute::name @name

• /descendant-or-self::node()/ is abbreviated to // child::aa/descendant-or-self::node()/child::bb aa//bb

• self::node() is abbreviated to . self::node()/descendant-or-self::node()/child::name .//name

• parent::node() is abbreviated to .. parent::node()/child::title ../title

• position()= is omitted [position()=1] [1]

Page 33: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

33Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• a selects the element children with name a of the context node• * selects all element children of the context node• text() selects all text children of the context node• node() selects all the element and text children of the context node• @a selects the attribute with name a of the context node• @* selects all the attributes of the context node• */a selects all element grandchildren with name a of the context node• a[1] selects the first element child with name a of the context node• a[last()] selects the last element child with name a of the context node• /doc/chapter[5]/section[2] is an abbreviation of /child::doc/child::chapter[position()=5]/child::section[position()=2]• chapter//a is an abbreviation of chapter/descendant-or-self::node()/child::a• //a is an abbreviation of /descendant-or-self::node()/child::a • ./a is an abbreviation of self::node()/child::a, which is equivalent to child::a • chapter/./a is an abbreviation of child::chapter/self::node()/child::a, which is equivalent to child::chapter/child::a or chapter/a • */.. is an abbreviation of child::*/parent::node() selects the context node, if it has children, otherwise nothing is selected• //a[1] is an abbreviation of /descendant-or-self::node()/child::a[position()=1] and selects the name descendant elements of the root that are the first name child of their parent• /descendant::a[1] is an abbreviation of /descendant::a[position()=1] and selects the first name descendant of the root

Page 34: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

34Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Predicates [3]

Predicates can be

• Boolean expression

[a/b/c/text()=5] 5 belongs to the result sequence of the location path[a/b/c=d/e] intersection of the 2 result sequences is not empty

• location path

[a/b/c] result sequence of location path is not empty

• number [5] means [position()=5]

• combinations using and, or, not

Page 35: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

35Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Note the difference between

• [a/text() = 12] selects a node if it has an a child with a text child equal to 12;

• [not(a/text() != 12)] selects a node if all the text children of all its a childeren are equal to 12;

(Cfr. Data Model p.12) • //Students/Student/@StudId[../Name/First[string(text())=“John”]

or ../CrsTaken[@Semester=“2”]]• //Students/Student[Name/First[string(text())=“John”] or CrsTaken[@Semester=“2”]]• //Students/Student/Status[../Name/First[string(text())=“John”]

or ../CrsTaken[@Semester=“2”]]• //Students/Student/Name[First[string(text())=“John”] or ../CrsTaken[@Semester=“2”]]• //Students/Student/Name/First[string(text())=“John” or ../../CrsTaken[@Semester=“2”]]

• //a/b[2] selects 2nd and 4th b• (//a/b)[2] selects 2nd b a a

b b b b

Page 36: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

36Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<?xml version="1.0"?><purchaseOrder orderDate=“2004-10-20"> <shipTo country="US"> <name>Alice Smith</name> <street>123 Maple Street</street> <city>Mill Valley</city> <state>CA</state> <zip>90952</zip> </shipTo> <billTo country="US"> <name>Robert Smith</name> <street>8 Oak Avenue</street> <city>Old Town</city> <state>PA</state> <zip>95819</zip> </billTo> <comment>Hurry, my lawn is going wild!</comment> <items> <item partNum="872-AA"> <productName>Lawnmower</productName> <quantity>1</quantity> <USPrice>148.95</USPrice> <comment>Confirm this is electric</comment> </item> <item partNum="926-AA"> <productName>Baby Monitor</productName> <quantity>1</quantity> <USPrice>39.98</USPrice> <shipDate>2004-12-21</shipDate> </item> </items> </purchaseOrder>

Document on file‘po.xml’, runningexample 3

Xpath as a Query Language for XML

Page 37: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

37Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Select the date of the purchase order if it is shipped to Belgium:document(“po.xml”)/purchaseOrder/@orderDate[../shipTo/@country=“Belgium”]document(“po.xml”)/purchaseOrder[shipTo/@country=“Belgium”]/@orderDate

Select the items that are shipped to Mechelen and whose price is greaterthan 40:document(“po.xml”)//item[USPrice/text()>40 and (../../billTo/city/text()="Mechelen")]

Select the purchase order if all its items cost more than 40:document(“po.xml”)/purchaseOrder[not(.//USPrice/text()<=40)]

Select the purchase order if some of its items cost more than 40:document(“po.xml”)/purchaseOrder[.//USPrice/text>40]

Select the purchase order if it contains at least 2 items:document(“po.xml”)/purchaseOrder[items/item[2]]

Given an item, select the preceding item of the same purchase order:preceding-sibling::*[1]

Select the dates on which there is an order that is shipped and billed inthe same city:document(“po.xml”)/purchaseOrder/@orderDate [../shipTo/city/text()=../billTo/city/text()]

Page 38: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

38Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

5. XQuery [4,5,6]

Principles of XQuery Design

• A set of operators that are closed under the data model;• Every expression has a value and no side effects;• Expressions can be composed with full generality;• Use the type system of XML Schema;• XPath compatibility. Adopt XPath as a syntactic subset;• Roughly equivalent to "relational completeness“;• No formal standard exists for hierarchic languages;• XQuery is a case-sensitive language• Keywords are in lower-case• Expressions can raise errors

Page 39: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

39Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• Recursive Functions;• Conciseness - Simplicity• Static Analysis

• optional static analysis phase before query execution• type inference rules based on XML Schema• early detection of some kinds of errors• optimization

• Comments look like this:(: Houston, we have a problem :)

Page 40: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

40Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

For overview: http://www.w3.org/XML/QueryDemos

• X-Hive's XQuery demo

• Software AG's Tamino XML Query Demo

Free and/or Open Source

• Fernandez/Simeon's Galax. Open-source.

• Saxonica's Saxon. Available in a schema-aware version as a commercial product, and without schema support as open source.

• Sourceforge's eXist. Open-source.

• Ispras Modis' Sedna. Open-source. … and many more …

Commerical

• BEA's Liquid Data

• X-Hive; Software AG’s Tamino;

• Microsoft's SQL Server 2005 Express, with XQuery support

• Oracle's Xquery Technology - Preview … and many many more …

Interesting Implementations

Page 41: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

41Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• Literals: "Hello" 47 4.7 4.7E-2• Constructed values:

true() false() date("2002-03-15")• Variables: $x• Constructed sequences

$a, $b is the same as ($a, $b)(1, (2, 3), (), (4)) is the same as 1, 2, 3, 45 to 8 is the same as 5, 6, 7, 8

• Functions• XQuery functions have expressions for bodies and may be

recursive• Function calls: two-argument-function(1, (2,3))• Functions are not overloaded (except certain built-ins)• Subtype substitutability in function arguments

XQuery Expressions

Page 42: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

42Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• Functions on sequences• union intersect except (infix) – only on sequences of nodes; result in doc. order without dupl.• empty() count()

• Location paths of XPath • abbreviated and non-abbreviated;• examples:

book[author/text() = "Mark Twain "]chapter[2]book[appendix]person[@married]//book[author/text() = "Mark Twain"]/chapter[2](1 to 100)[. mod 5=0]

• Arithmetic operators: + - * div idiv mod• Extract typed value from node• Multiple values => error• If operand is (), return ()• Supported for numeric and date/time types

Page 43: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

43Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• Comparison operators • eq ne gt ge lt le compare single atomic values• = != > >= < <= implied existential semantics• is, is not compare two nodes based on identity• << >> compare two nodes based on document order

Page 44: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

44Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• FLWOR Expression

A FLWOR expression binds some variables, applies apredicate and constructs a new result.

for var in expr

let var := expr

where expr

order by expr return expr

Page 45: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

45Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<?xml version="1.0"?><Classes> <Class CrsCode="CS308" Semester="F1997"> <CrsName>Market Analysis</CrsName> <Instructor>Adrian Jones</Instructor> </Class> <Class CrsCode="EE101" Semester="F1995"> <CrsName>Electronic Circuits</CrsName> <Instructor>David Jones</Instructor> </Class> <Class CrsCode="CS305" Semester="F1995"> <CrsName>Database Systems</CrsName> <Instructor>Mary Doe</Instructor> </Class></Classes><?xml version="1.0"?>

<Transcripts> <Transcript> <Student StudId="111111111" Name="John Doe"/> <CrsTaken CrsCode="CS308" Semester="F1990" Grade="B"/> <CrsTaken CrsCode="MAT123" Semester="F1997" Grade="B"/> <CrsTaken CrsCode="EE101" Semester="F1997" Grade="A"/> <CrsTaken CrsCode="CS305" Semester="F1995" Grade="A"/> </Transcript> <Transcript> <Student StudId="987654321" Name="Bart Simpson"/> <CrsTaken CrsCode="CS305" Semester="F1995" Grade="C"/> <CrsTaken CrsCode="CS308" Semester="F1994" Grade="B"/> </Transcript></Transcripts>

Examplesin Galax

transcripts.xml

classes.xml

Page 46: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

46Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

– FOR clausefor $c in document(“classes.xml”)//Class, $t in document(“transcripts.xml”)//Transcript

• specify documents used in the query• declare variables and bind them to a range • result is a list of bindings

– LET clauselet $sn := $t/Student/@Name, $cn := $c/CrsName

• bind variables to a value– WHERE clause

where $c/@CrsCode = $t/CrsTaken/@CrsCode and $c/@Semester = $t/CrsTaken/@Semester

• selects a sublist of the list of bindings– RETURN clause

return <CrsStud> $cn <Name> $sn </Name> </CrsStud>

• construct result for every selected binding

Page 47: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

47Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<StudentList>{for $t in document(“transcripts.xml”)//Transcriptlet $s := $t/Student

where $t/CrsTaken/@CrsCode = “CS308”return <Stud id=“{$s/@StudId}”> {$s/@Name} </Stud>}</StudentList>

<StudentList> <Stud id="111111111" Name="John Doe"/> <Stud id="987654321" Name="Bart Simpson"/></StudentList>

q01.xq

Page 48: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

48Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• Element Constructor<book isbn="12345"><title>Huckleberry Finn</title></book>

The result of an element constructor is a new element node, with its own node identity. All the attribute and descendant nodes of the new element node are also new nodes with their own identities, even if they are copies of existing nodes.

Page 49: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

49Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

If the content of an element or attribute must be computed, use a nested expression enclosed in { }<book isbn="{$x}">{$b/title}</book>

<e> <p r="[1,5 to 7,9]"> AA </p> <eg> $i//t </eg>

<p r="[{1, 5 to 7, 9}]"> BB </p> <eg> {$i//t} </eg> </e> The above query might generate the following result:<e> <p r="[1,5 to 7,9]"> AA </p> <eg> $i//t </eg>

<p r="[1,5,6,7,9]"> BB </p> <eg> <t>CC</t> </eg> </e>

<a>{1, 2, 3}</a> The constructed element node has one child, a text node containing the value "1 2 3".

<fact>I saw <howmany>{5 + 3}</howmany> cats.</fact> The constructed element node has three children: a text node containing "I saw ", a child element node named howmany, and a text node containing " cats.". The child element node in turn has a single text node child containing the value "8".

Page 50: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

50Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

doc1.xml

<docu><el a1="v1" a2="v2"> <sub> v3 </sub> <sub> v4 </sub></el><el a1="v5"> <sub> v6 </sub></el><el a1="v7"/></docu>

q14.xq

for $e in document("doc1.xml")//elreturn $e,for $e in document("doc1.xml")//elreturn <k> $e/@a1 </k>,for $e in document("doc1.xml")//elreturn <k2> {$e/@a1} </k2>,for $e in document("doc1.xml")//elreturn <k3 a1="{$e/@a1}" />,for $e in document("doc1.xml")//elreturn <k4 b="{$e/@a1}" />,for $e in document("doc1.xml")//elreturn <k5> {string($e/@a1)} </k5>,for $e in document("doc1.xml")//elfor $s in $e/subreturn <k6> {data($s)} </k6>,for $e in document("doc1.xml")//elfor $s in $e/subreturn <k7> {$s/text()} </k7>

Result

<el a1="v1" a2="v2"><sub> v3 </sub><sub> v4 </sub></el>,<el a1="v5"><sub> v6 </sub></el>, <el a1="v7"/>, <k> $e/@a1 </k>,<k> $e/@a1 </k>, <k> $e/@a1 </k>, <k2 a1="v1"/>, <k2 a1="v5"/>, <k2 a1="v7"/>,<k3 a1="v1"/>, <k3 a1="v5"/>, <k3 a1="v7"/>, <k4 b="v1"/>, <k4 b="v5"/>,<k4 b="v7"/>, <k5>v1</k5>, <k5>v5</k5>, <k5>v7</k5>, <k6> v3 </k6>,<k6> v4 </k6>, <k6> v6 </k6>, <k7> v3 </k7>, <k7> v4 </k7>, <k7> v6 </k7>

The functions data() and string() give the content of their arguments (Cfr. later)

Page 51: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

51Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

If both the name and the content must be computed, use acomputed constructor:element{name-expr}{content-expr}attribute{name-expr}{content-expr}

The first enclosed expression after the element keyword generates the name of the element, and the second enclosed expression generates the content and attributes:

element {string(<f>nnn</f>)} {string(<e> sss</e>)},let $dict := <dic> <entry word="address"><variant lang="German">Adresse</variant><variant lang="Italian">Indirizzo</variant> </entry> </dic>let $e:=<address>123 Roosevelt Ave. Flushing, NY 11368</address> return element {string($dict/entry[@word=name($e)]/variant[@lang="Italian"])}{$e/@*, string($e)}

results in

<nnn> sss</nnn>, <Indirizzo>123 Roosevelt Ave. Flushing, NY 11368</Indirizzo>

q15.xq

Page 52: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

52Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

for $c in document("classes.xml")//Class, $t in document("transcripts.xml")//Transcriptwhere $c/@CrsCode = $t/CrsTaken/@CrsCode and $c/@Semester = $t/CrsTaken/@Semesterreturn <CrsStud> {$c/CrsName} <StudName> {$t/Student/@Name} </StudName> </CrsStud>

<CrsStud> <CrsName>Market Analysis</CrsName> <StudName Name="John Doe"/></CrsStud>,<CrsStud> <CrsName>Electronic Circuits</CrsName> <StudName Name="John Doe"/></CrsStud>,<CrsStud> <CrsName>Database Systems</CrsName> <StudName Name="John Doe"/></CrsStud>,<CrsStud> <CrsName>Database Systems</CrsName> <StudName Name="Bart Simpson"/></CrsStud>

Flat Join(wrong resultcfr. next slide)

q02.xq

Page 53: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

53Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<?xml version="1.0"?><Classes> <Class CrsCode="CS308" Semester="F1997"> <CrsName>Market Analysis</CrsName> <Instructor>Adrian Jones</Instructor> </Class> <Class CrsCode="EE101" Semester="F1995"> <CrsName>Electronic Circuits</CrsName> <Instructor>David Jones</Instructor> </Class> <Class CrsCode="CS305" Semester="F1995"> <CrsName>Database Systems</CrsName> <Instructor>Mary Doe</Instructor> </Class></Classes><?xml version="1.0"?>

<Transcripts> <Transcript> <Student StudId="111111111" Name="John Doe"/> <CrsTaken CrsCode="CS308" Semester="F1990" Grade="B"/> <CrsTaken CrsCode="MAT123" Semester="F1997" Grade="B"/> <CrsTaken CrsCode="EE101" Semester="F1997" Grade="A"/> <CrsTaken CrsCode="CS305" Semester="F1995" Grade="A"/> </Transcript> <Transcript> <Student StudId="987654321" Name="Bart Simpson"/> <CrsTaken CrsCode="CS305" Semester="F1995" Grade="C"/> <CrsTaken CrsCode="CS308" Semester="F1994" Grade="B"/> </Transcript></Transcripts>

Why<CrsStud> <CrsName>Market Analysis</CrsName> <StudName Name="John Doe"/></CrsStud>,

is in the result

transcripts.xml

classes.xml

Page 54: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

54Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

for $c in document("classes.xml")//Class, $t in document("transcripts.xml")//Transcript, $ct in $t/CrsTakenwhere $c/@CrsCode = $ct/@CrsCode and $c/@Semester = $ct/@Semesterreturn <CrsStud> {$c/CrsName} <StudName> {$t/Student/@Name} </StudName> </CrsStud>

<CrsStud> <CrsName>Database Systems</CrsName> <StudName Name="John Doe"/></CrsStud>,<CrsStud> <CrsName>Database Systems</CrsName> <StudName Name="Bart Simpson"/></CrsStud>

• Order of variables in FOR-clause matters.• Classes with no transcripts are omitted.

q03.xq

Flat join

Page 55: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

55Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

for $c in document("classes.xml")//Classorder by ($c/CrsName/text())return( <CrsStud CrsName="{$c/CrsName/text()}"> { for $t in document("transcripts.xml")//Transcript for $ct in $t/CrsTaken where ($c/@CrsCode = $ct/@CrsCode and $c/@Semester = $ct/@Semester) return <StudName> {$t/Student/@Name}</StudName> } </CrsStud>)

<CrsStud CrsName="Database Systems"> <StudName Name="John Doe"/> <StudName Name="Bart Simpson"/></CrsStud>, <CrsStud CrsName="Electronic Circuits"/>,<CrsStud CrsName="Market Analysis"/>

Nested Join

q04.xq

Page 56: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

56Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Group students per course code and semester on the basis of Transcripts alonelet $trs := document("transcripts.xml")//Transcriptlet $ct := $trs/CrsTakenfor $c in $ctreturn <CrsStud CrsCode="{$c/@CrsCode}" Semester="{$c/@Semester}">{ for $t in $trs where (($c/@CrsCode = $t/CrsTaken/@CrsCode) and ($c/@Semester = $t/CrsTaken/@Semester)) order by ($t/Student/@StudId) return $t/Student} </CrsStud>

q05.xq

<CrsStud CrsCode="CS308" Semester="F1990"> <Student StudId="111111111" Name="John Doe"/></CrsStud>,<CrsStud CrsCode="MAT123" Semester="F1997"> <Student StudId="111111111" Name="John Doe"/></CrsStud>,<CrsStud CrsCode="EE101" Semester="F1997"> <Student StudId="111111111" Name="John Doe"/></CrsStud>,<CrsStud CrsCode="CS305" Semester="F1995"> <Student StudId="111111111" Name="John Doe"/> <Student StudId="987654321" Name="Bart Simpson"/></CrsStud>,<CrsStud CrsCode="CS305" Semester="F1995"> <Student StudId="111111111" Name="John Doe"/> <Student StudId="987654321" Name="Bart Simpson"/></CrsStud>,<CrsStud CrsCode="CS308" Semester="F1994"> <Student StudId="987654321" Name="Bart Simpson"/></CrsStud>

Page 57: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

57Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• User-defined functions local: is only necessary in GALAX, not necessary in XQuery;

Count number of descendants

declare function local:countElemNodes($e) { if (empty($e/*)) then 0 else local:countElemNodes($e/*) + count($e/*)};

local:countElemNodes(document("transcripts.xml")//Transcripts)

Result : 10

• Input and output are typed• Body can be any XQuery expression,

recursion is allowed• XPath core functions: sum(), count()• Automatic generalization of local:countElemNodes() to collection

q06.xq

Page 58: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

58Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Group students per course code and semester on basis of Transcripts alone q13.xq

declare function local:extractClasses($e) {

for $c in $e//CrsTaken

return <Class CrsCode="{$c/@CrsCode}" Semester="{$c/@Semester}"/>

};

let $trs := document("transcripts.xml")/Transcripts

for $c in local:extractClasses($trs)

return

<ClassRoster>

{ $c/@CrsCode, $c/@Semester }

{ for $t1 in $trs//Transcript[CrsTaken/@CrsCode=$c/@CrsCode and

CrsTaken/@Semester=$c/@Semester]

order by ($t1/Student/@StudentId)

return $t1/Student

}

</ClassRoster>

Page 59: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

59Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Result

<ClassRoster CrsCode="CS308" Semester="F1990"> <Student StudId="111111111" Name="John Doe"/></ClassRoster>,<ClassRoster CrsCode="MAT123" Semester="F1997"> <Student StudId="111111111" Name="John Doe"/></ClassRoster>,<ClassRoster CrsCode="EE101" Semester="F1997"> <Student StudId="111111111" Name="John Doe"/></ClassRoster>,<ClassRoster CrsCode="CS305" Semester="F1995"> <Student StudId="111111111" Name="John Doe"/> <Student StudId="987654321" Name="Bart Simpson"/></ClassRoster>,<ClassRoster CrsCode="CS305" Semester="F1995"> <Student StudId="111111111" Name="John Doe"/> <Student StudId="987654321" Name="Bart Simpson"/></ClassRoster>,<ClassRoster CrsCode="CS308" Semester="F1994"> <Student StudId="987654321" Name="Bart Simpson"/></ClassRoster>

Page 60: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

60Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Give all the elements in classes that contain somewhere “ys” and whose elementname ends with “ses”

<StudentList>{ for $t in document("classes.xml")//*[contains(string(.), "ys") and ends-with(name(.),"ses")] return $t}</StudentList>

<StudentList> <Classes> <Class CrsCode="CS308" Semester="F1997"> <CrsName>Market Analysis</CrsName> <Instructor>Adrian Jones</Instructor> </Class> <Class CrsCode="EE101" Semester="F1995"> <CrsName>Electronic Circuits</CrsName> <Instructor>David Jones</Instructor> </Class> <Class CrsCode="CS305" Semester="F1995"> <CrsName>Database Systems</CrsName> <Instructor>Mary Doe</Instructor> </Class> </Classes></StudentList>

Cfr.www.w3.org/TR/xquery-operators

q17.xq

Page 61: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

61Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

>>, << document order<ua>{for $c1 in document("transcripts.xml")//CrsTaken[@Semester > "F1994"]for $c2 in document("transcripts.xml")//CrsTaken[@Semester > "F1994"] where (($c1 << $c2) and not($c1/@Grade = $c2/@Grade)) return <ff> {$c1, $c2} </ff>}</ua><ua> <ff> <CrsTaken CrsCode="MAT123" Semester="F1997" Grade="B"/> <CrsTaken CrsCode="EE101" Semester="F1997" Grade="A"/> </ff> <ff> <CrsTaken CrsCode="MAT123" Semester="F1997" Grade="B"/> <CrsTaken CrsCode="CS305" Semester="F1995" Grade="A"/> </ff> <ff> <CrsTaken CrsCode="MAT123" Semester="F1997" Grade="B"/> <CrsTaken CrsCode="CS305" Semester="F1995" Grade="C"/> </ff> <ff> <CrsTaken CrsCode="EE101" Semester="F1997" Grade="A"/> <CrsTaken CrsCode="CS305" Semester="F1995" Grade="C"/> </ff> <ff> <CrsTaken CrsCode="CS305" Semester="F1995" Grade="A"/> <CrsTaken CrsCode="CS305" Semester="F1995" Grade="C"/> </ff></ua>

q18.xq

Page 62: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

62Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

let $doc := <a> <b> aa </b> <c> 1 </c> <c> 2 </c> <b> bb </b> <c> 3 </c> <c> 4 </c> <c> 5 </c> </a>let $i1 := $doc//b[2]for $i2 in $doc//c[. >> $i1][position()<=2]return $i2/text()

text {“ 3 ”}, text {“ 4 “}

let $doc := <a> <c> 1 </c> <c> 2 </c> <b> bb </b> <c> 3 </c> <c> 4 </c> <c> 5 </c> </a>for $i2 in $doc//cwhere not(some $i1 in $doc//b satisfies ($i1 << $i2))return $i2/text()

text {“ 1 ”}, text {“ 2 “}

let $doc := <a> <c> 1 </c> <b> <c> 2 </c> bb </b> <c> 3 </c> <c> 4 </c> <c> 5 </c> </a>for $i2 in $doc//cwhere not(some $i1 in $doc//b satisfies ($i1 << $i2))return $i2/text()

text {“ 1 “}

q19.xq

q21.xq

q20.xq

Page 63: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

63Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Find everything between two nodes

declare function local:btween($seq, $start, $enda) { let $nodes := for $n in $seq except $start//node() where $n >> $start and $n << $enda return $n return ($nodes except $nodes//node())};

<c_s>{let $proc := (<a> <c> 1 <b> fff </b> </c> <b> <c> 2 </c> bb </b> <c> 3 </c> <c> 4 </c> <c> 5 </c> </a>), $first := $proc/c[1], $second := $proc/c[last()]return local:btween($proc//node(), $first, $second) }</c_s>

<c_s><b><c> 2 </c> bb </b><c> 3 </c><c> 4 </c></c_s>

q22.xq

Page 64: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

64Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<c_s>{let $proc := (<abc> cxcxc <cdf> 1 <bef> fffc </bef> </cdf> <bfg> <c> 2 </c> cbb </bfg> <cgl> 3 </cgl> <cgt> 4 </cgt> <csd> c5 </csd> </abc>)return $proc//node()[contains(.,"c")]}</c_s>

<c_s> cxcxc <cdf> 1 <bef> fffc </bef></cdf> <bef> fffc </bef> fffc <bfg><c> 2 </c> cbb </bfg> cbb <csd> c5 </csd> c5</c_s>

q23.xq

Page 65: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

65Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

declare function local:one_level($l, $p) { <part partid="{ $p/@partid }" name="{ $p/@name }" > { for $s in $l//part where $s/@partof = $p/@partid return local:one_level($l,$s) } </part>};

let $list := <partlist> <part partid="0" name="car"/> <part partid="1" partof="0" name="engine"/> <part partid="2" partof="0" name="door"/> <part partid="3" partof="1" name="piston"/> <part partid="4" partof="2" name="window"/> <part partid="5" partof="2" name="lock"/> <part partid="10" name="skateboard"/> <part partid="11" partof="10" name="board"/> <part partid="12" partof="10" name="wheel"/> <part partid="20" name="canoe"/></partlist>

return(<parttree> { for $p in $list//part[empty(@partof)] return local:one_level($list,$p) }</parttree>)

<parttree> <part partid="0" name="car"> <part partid="1" name="engine"> <part partid="3" name="piston"/></part> <part partid="2" name="door"> <part partid="4" name="window"/> <part partid="5" name="lock"/> </part> </part> <part partid="10" name="skateboard"> <part partid="11" name="board"/> <part partid="12" name="wheel"/> </part> <part partid="20" name="canoe"/></parttree>

q24.xq

Page 66: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

66Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Grouping and aggregation

Count courses per student

for $t in document("transcripts.xml")//Transcript,

$s in $t/Student

let $c := $t/CrsTaken

return

<StudentSummary StudId="{$s/@StudId}" Name="{$s/@Name}"

TotalCourses="{count($c)}"/>

<StudentSummary StudId="111111111" Name="John Doe" TotalCourses="4"/>,

<StudentSummary StudId="987654321" Name="Bart Simpson" TotalCourses="2"/>

q08.xq

Page 67: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

67Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Compute average grade per class q09.xq

declare function local:numericGrade($a) {

let $grade := data($a)

return

if ($grade = "A") then 10 else if ($grade = "B") then 8

else if ($grade = "C") then 6 else if ($grade = "D") then 4

else if ($grade = "E") then 2 else 0

};

for $c in document("classes.xml")//Class

let $g := ( for $ct in document("transcripts.xml")//CrsTaken

where $ct/@CrsCode = $c/@CrsCode

and $ct/@Semester = $c/@Semester

return local:numericGrade($ct/@Grade)

)

order by ($c/@CrsCode)

return

<ClassSummary CrsCode="{string($c/@CrsCode)}" Semester="{string($c/@Semester)}"

CrsName="{$c/CrsName/text()}" Instructor="{$c/Instructor/text()}"

AvgGrade="{ if (count($g) > 0) then avg($g) else 0}"/>

<ClassSummary CrsCode="CS305" Semester="F1995" CrsName="Database Systems" Instructor="Mary Doe" AvgGrade="8"/>,<ClassSummary CrsCode="CS308" Semester="F1997" CrsName="Market Analysis" Instructor="Adrian Jones" AvgGrade="0"/>,<ClassSummary CrsCode="EE101" Semester="F1995" CrsName="Electronic Circuits" Instructor="David Jones" AvgGrade="0"/>

Page 68: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

68Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• Quantification

– Existential quantification: • some $Var in Expr satisfies Cond

– Universal quantification:• every $Var in Expr satisfies Cond

Select courses that were followed by some student

q10.xq

for $c in document("classes.xml")//Classwhere ( some $t in document("transcripts.xml")//CrsTaken satisfies ($c/@CrsCode = $t/@CrsCode and $c/@Semester = $t/@Semester))return $c/CrsName

<CrsName>Database Systems</CrsName>

Page 69: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

69Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Select classes in which every student took MAT123for $c in document("classes.xml")//Classlet $g := ( for $t in document("transcripts.xml")//Transcript let $tt := for $b in $t/CrsTaken where $b/@CrsCode = $c/@CrsCode and $b/@Semester = $c/@Semester return $b where not(empty($tt)) return $t )where every $tr in $g satisfies not(empty($tr[CrsTaken/@CrsCode = "MAT123"]))order by ($c/CrsCode)return $c

<Class CrsCode="CS308" Semester="F1997"> <CrsName>Market Analysis</CrsName> <Instructor>Adrian Jones</Instructor></Class>,<Class CrsCode="EE101" Semester="F1995"> <CrsName>Electronic Circuits</CrsName> <Instructor>David Jones</Instructor></Class>

q11.xq

Page 70: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

70Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Order sorts a list <ll> … </ll> of elements on their names.declare function local:Car($x){if (empty($x/*)) then <ll/> else for $y at $z in $x/* where $z=1 return $y};

declare function local:Cdr($x){if (empty($x/*)) then <ll/> else <ll> {for $y at $z in $x/* where 1 lt $z return $y} </ll>};

declare function local:Cons($x, $y) {<ll> {$x, $y/*} </ll> };

declare function local:Decomp($x) {if (empty($x/*)) then <ll> {$x, $x} </ll> else if (count($x/*) eq 1) then (<ll> <ll/> {$x} </ll>) else <ll> {local:Decomp(local:Cdr($x))/*[2]} <ll>{local:Car($x), local:Decomp(local:Cdr($x))/*[1]/*} </ll> </ll>};

declare function local:Merge($x, $y){if (empty($x/*)) then $y else if (empty($y/*)) then $x else if (name($x/*[1]) lt name($y/*[1])) then local:Cons($x/*[1], local:Merge(local:Cdr($x), $y)) else local:Cons($y/*[1], local:Merge(local:Cdr($y), $x))};

declare function local:Order($x){if (count($x/*) lt 2) then $x else let $t := local:Decomp($x) let $t1 := local:Car($t) let $t2 := local:Car(local:Cdr($t)) return local:Merge(local:Order($t1),local:Order($t2))};

let $l5 := <ll> <ss/> <vv/> <df/> <fr/> <ds/> <as/> <gy/> <qn/> <cm/> <an/> <fg/> </ll>return local:Order($l5)

<ll><an/><as/><cm/><df/><ds/><fg/><fr/><gy/><qn/><ss/><vv/></ll>

q16.xq

The function name($e) gives the name of the element $e (Cfr. later)

Page 71: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

71Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

XQuery Data Model

• Sequences are list of 0 or more items;• an item is a node or an atomic value;• a sequence of one item is equiv. with that item;• a sequencetype consists of a typename and an

occurrence indicator;xs:integer* xs:integer+ xs:integer?

6 Typing in XQuery [10]

Page 72: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

72Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Atomic Types

Built-in atomic types are defined in two namespaces:xs: (http://www.w3.org/2001/XMLSchema)

xdt: (http://www.w3.org/2003/11/xpath-datatypes)

xdt:anyAtomicType

xdt:untypedAtomic xs:boolean

xs:double xs:decimal

xs:integer

xs:float

xs:string

Page 73: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

73Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

xdt:untypedAtomic• numbers are double, rest are string• avoids castingxs:boolean• true(), false()numerical types• xs:double, xs:decimal, xs:integer, xs:float

Type constructors are used to create values of thattype (complex rules for errors)xs:integer("12") => 12xs:integer(56) => 56xs:boolean(“true”) => true()xs:boolean(“1”) => true()xs:boolean(“false”) => false()xs:boolean(“0”) => false()xs:boolean(other) => error

12 => 12xs:integer(<a> 78 </a>) => 78xs:integer(“4.5”) => errorxs:float("2.88") => xs:float(“2.88”)xs:float("567") => xs:float(“567”)xs:float(567) => xs:float(“567”)xs:decimal(3.8) => 3.8xs:decimal("3.8") => 3.8xs:decimal(3) => 3xs:decimal("3") => 3

Page 74: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

74Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Node kinds

Nodes are part of a document or a fragment (whose root

is not a document node).

We consider 4 node kinds: element, attributetext, document-node also comment, namespace, processing-instruction.

Every node has type node(); other types areitem(), element(), attribute(), document-node(), text()

Page 75: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

75Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• name() is a function that give the name (type string) of a node;• string() takes a node and gives the concatenation of the string values of all its descendants;• data() takes a sequence of items (with each node having a single atomic value) and gives the sequence of the typed atomic values of the items.• boolean() takes a sequence of items and returns a boolean value;empty sequence, empty string, 0, false() => false()other sequences => true()

• instance of takes a value and a type andverifies whether the value is of that type;

Page 76: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

76Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• v cast as t has the same meaning as t(v);• v castable as t => true() iff v cast t gives no error;

name(<a/>),string(<a> cdf <b> 3<c> 4 </c><c>aa</c>1q2</b>;</a>),data((1, 3.4, 3.4E2, <a>34</a>, <a xsi:type="xs:integer">34</a>)),boolean(""), boolean(123), boolean((0,0))=>“a”, “ cdf 3 4 aa1q2;”, 1, 3.4, 340, xdt:untypedAtomic(“34”),xs:integer(“34”), false(), true(), true()!not in Galax!

<x/> instance of element(),1 instance of xs:integer,1 instance of item()*,(1,2,7) instance of xs:integer*,(1,2,7) instance of xs:integer+,(1,2,7) instance of xs:integer?,(let $s := "Antwerp" return $s instance of xs:string)=>true(), true(), true(), true(), true(), false(), true()

“2” cast as xs:integer => 2“2” castable as xs:integer => true()

Page 77: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

77Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Function declarations with types

type of the arguments and type of the result arementioned:

declare function f(p as t1, p2 as t2) as t3 { … };

Page 78: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

78Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

declare function local:seconditin($seq as item()*) as xs:integer(: gives the second item of a sequence :){ $seq[2] };

declare function local:secondinin($seq as xs:integer*) as xs:integer(: gives the second item of a sequence :){ $seq[2] };

declare function local:seconditit($seq as item()*) as item()(: gives the second item of a sequence :){ $seq[2] };

local:seconditin((3, 7, <a>45</a>, 6.7)) => 7local:seconditin((3, <a>45</a>, 6.7)) => 45local:seconditin((3, <a>gg</a>, 6.7)) => text: “gg” is not an integer

local:secondinin((3, 7, 45, 6)) => 7local:secondinin((3, 7, 45, 6.7)) => cannot promote xs:decimal to xs:integerlocal:secondinin((3, 7, <a>45</a>, 6.7)) => cannot promote xs:decimal to xs:integerlocal:secondinin((3, 7, <a>gg</a>, 6.7)) => text: “gg” is not an integer

local:seconditit((3, 7, <a>45</a>, 6.7)) => 7local:seconditit((3, <a>45</a>, 6.7)) => <a>45</a>local:seconditit((3, <a>gg</a>, 6.7)) => <a>gg</a>local:seconditit((3, 7, 45, 6)) => 7local:seconditit((3, 7, 45, 6.7)) => 7local:seconditit((3, 7, <a>45</a>, 6.7)) => 7local:seconditit((3, 7, <a>gg</a>, 6.7)) => 7

Page 79: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

79Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Convert all attributes to elementsdeclare function local:convertAttribute($a as attribute()*) as element()* { for $attrib in $a let $name := name($attrib) return <element name="{$name}">

{data($attrib)}</element>

};

declare function local:convertElement($e as element()*) as element()* { for $el in $e let $name := name($el) return <element name="{$name}">{ local:convertAttribute($el/@*), if (empty($el/*)) then $el/text() else local:convertElement($el/*) }</element>};

local:convertElement(document("transcripts.xml")//Transcript)

Fails for elements with mixed (elements & text) content.

q07.xq

Page 80: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

80Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<element name="Transcript"> <element name="Student"> <element name="StudId">111111111</element> <element name="Name">John Doe</element> </element> <element name="CrsTaken"> <element name="CrsCode">CS308</element> <element name="Semester">F1990</element> <element name="Grade">B</element> </element> <element name="CrsTaken"> <element name="CrsCode">MAT123</element> <element name="Semester">F1997</element> <element name="Grade">B</element> </element> <element name="CrsTaken"> <element name="CrsCode">EE101</element> <element name="Semester">F1997</element> <element name="Grade">A</element> </element> <element name="CrsTaken"> <element name="CrsCode">CS305</element> <element name="Semester">F1995</element> <element name="Grade">A</element> </element></element>,

<element name="Transcript"> <element name="Student"> <element name="StudId">987654321</element> <element name="Name">Bart Simpson</element> </element> <element name="CrsTaken"> <element name="CrsCode">CS305</element> <element name="Semester">F1995</element> <element name="Grade">C</element> </element> <element name="CrsTaken"> <element name="CrsCode">CS308</element> <element name="Semester">F1994</element> <element name="Grade">B</element> </element></element>

Page 81: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

81Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Convert all nodes to elements q12.xq

declare function local:convertNode($n as node()) as element() {typeswitch ($n)case attribute() return <attribute name="{name($n)}">{

data($n)}</attribute>case element() return <element name="{name($n)}">{

for $attr in $n/@* return local:convertNode($attr),for $child in $n/node() return local:convertNode($child)

}</element>case text() return <text>{

data($n)}</text>default return <other>{

data($n)}</other>

};

local:convertNode(document("mixed.xml")/mixed)

• Can be used with user-defined types in imported schemas• Supports mixed content model

Page 82: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

82Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<?xml version="1.0"?><mixed>

<head><title>Mixed Content Example</title>

</head>

<body><p align="center">This paragraph contains <strong>mixed content</strong> whichis no more than <i>a piece of data mixed with some tags</i>.</p></body>

</mixed>

becomes next slide

Page 83: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

83Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<element name="mixed"> <text> </text> <element name="head"> <text> </text> <element name="title"><text>Mixed Content Example</text></element> <text> </text> </element> <text> </text> <element name="body"> <text> </text> <element name="p"> <attribute name="align">center</attribute> <text>This paragraph contains </text> <element name="strong"><text>mixed content</text></element> <text> which is no more than </text> <element name="i"> <text>a piece of data mixed with some tags</text> </element> <text>.</text> </element> <text> </text> </element> <text></text></element>

Page 84: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

84Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

7 Document Type Definitions [4]

• DTD is a grammar that specifies valid XML-documents;• XML-documents do not need to have a DTD, nor do they

need to be valid;

Page 85: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

85Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

An attribute can be declared of type CDATA, ID, IDREF or IDREFS;

– if attr1 and attr2 are declared of type ID then <elem1 attr1=“abc” /> and <elem2 attr2=“abc” />

cannot occur in the same document;

– an attribute of type IDREF must refer to an ID-value in

the same document;

if there is an a with <a a1=“abc”/> and a1 of

type IDREF then there is a b with

<b a2=“abc”/> and a2 of type ID – an attribute of type IDREFS represents a space-separated

list of references to ID-values in the same document;

if there is an a with <a a1=“abc def”/> and

a1 of type IDREFS then there is a b and a c with

<b a2=“abc”/> <c a3=“def”/> and a2 and

a3 of type ID

Page 86: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

86Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<!DOCTYPE PersonList [

<!ELEMENT PersonList (Title,Contents)>

<!ELEMENT Title EMPTY>

<!ELEMENT Contents (Person*)>

<!ELEMENT Person ((Name,Id,Address)|(Name))>

<!ELEMENT Name (#PCDATA)>

<!ELEMENT Id (#PCDATA)>

<!ELEMENT Address (Number,Street)>

<!ELEMENT Number (#PCDATA)>

<!ELEMENT Street (#PCDATA)>

<!ATTLIST PersonList Type CDATA #IMPLIED

Date CDATA #IMPLIED>

<!ATTLIST Title Value CDATA #REQUIRED>

]>

• the order of the subelements has to be obeyed;• * [0,[, + [1, [, ?[0,1], | alternatives;• #PCDATA : (Parsed Character Data) : character string for elements (unquoted);• CDATA : (Character Data) : character string for attributes (quoted);• IMPLIED : optional;• REQUIRED : mandatory;

Page 87: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

87Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<!DOCTYPE Report [ <!ELEMENT Report (Students,Classes,Courses)> <!ELEMENT Students (Student*)> <!ELEMENT Classes (Class*)> <!ELEMENT Courses (Course*)> <!ELEMENT Student (Name,Status,CrsTaken*)> <!ELEMENT Name (First,Last)> <!ELEMENT First (#PCDATA)> . . . <!ELEMENT CrsTaken EMPTY> <!ELEMENT Class (CrsCode,Semester,ClassRoster)> <!ELEMENT Course (CrsName)> . . . <!ELEMENT ClassRoster EMPTY> <!ATTLIST Report Date #IMPLIED> <!ATTLIST Student Studld ID #REQUIRED> <!ATTLIST Course CrsCode ID #REQUIRED> <!ATTLIST CrsTaken CrsCode IDREF #REQUIRED> <!ATTLIST CrsTaken Semester IDREF #REQUIRED> <!ATTLIST ClassRoster Members IDREFS #IMPLIED>]>

DTD for running example 2

Page 88: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

88Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

8 XML Schema [1,2]

• XML Schema is as a DDL for XML-documents;it describes the structure of other instance XML-documents;

• Advantages over DTD :– uses the same syntax as XML-documents;– integrates namespace mechanism;– built-in types;– complex types can be built from simple types;– references can be typed;– supports keys and referential integrity constraints;– same element name can have different types

depending where the element name is nested;– XML data do not need to be ordered;

Page 89: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

89Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• elements and attributes have types;• elements that contain subelements have complex types;• elements with attributes have complex types;• other elements have simple types;• attributes have simple types; • types are given names or are anonymous;• schema is defined in a schema XML document;• we presume (for the moment (Cfr. later)) that the

instance • document is not referring to the schema document;

Page 90: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

90Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<?xml version="1.0"?><purchaseOrder orderDate=“2004-10-20"> <shipTo country="US"> <name>Alice Smith</name> <street>123 Maple Street</street> <city>Mill Valley</city> <state>CA</state> <zip>90952</zip> </shipTo> <billTo country="US"> <name>Robert Smith</name> <street>8 Oak Avenue</street> <city>Old Town</city> <state>PA</state> <zip>95819</zip> </billTo> <comment>Hurry, my lawn is going wild!</comment> <items> <item partNum="872-AA"> <productName>Lawnmower</productName> <quantity>1</quantity> <USPrice>148.95</USPrice> <comment>Confirm this is electric</comment> </item> <item partNum="926-AA"> <productName>Baby Monitor</productName> <quantity>1</quantity> <USPrice>39.98</USPrice> <shipDate>2004-12-21</shipDate> </item> </items> </purchaseOrder>

Document on file‘po.xml’, runningexample 3

Page 91: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

91Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<xsd:annotation> <xsd:documentation xml:lang="en"> Purchase order schema for Example.com. Copyright 2000 Example.com. All rights reserved. </xsd:documentation> </xsd:annotation>

<xsd:element name="purchaseOrder" type="PurchaseOrderType"/> <xsd:element name="comment" type="xsd:string"/>

<xsd:complexType name="PurchaseOrderType"> <xsd:sequence> <xsd:element name="shipTo" type="USAddress"/> <xsd:element name="billTo" type="USAddress"/> <xsd:element ref="comment" minOccurs="0"/> <xsd:element name="items" type="Items"/> </xsd:sequence> <xsd:attribute name="orderDate" type="xsd:date"/> </xsd:complexType>

<xsd:complexType name="USAddress"> <xsd:sequence> <xsd:element name="name" type="xsd:string"/> <xsd:element name="street" type="xsd:string"/> <xsd:element name="city" type="xsd:string"/> <xsd:element name="state" type="xsd:string"/> <xsd:element name="zip" type="xsd:decimal"/> </xsd:sequence> <xsd:attribute name="country" type="xsd:NMTOKEN"/> </xsd:complexType>

Schema documenton file ‘po.xsd’,running example 3

Page 92: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

92Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<xsd:complexType name="Items"> <xsd:sequence> <xsd:element name=“Item" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:sequence> <xsd:element name="productName" type="xsd:string"/> <xsd:element name="quantity"> <xsd:simpleType> <xsd:restriction base="xsd:positiveInteger"> <xsd:maxExclusive value="100"/> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="USPrice" type="xsd:decimal"/> <xsd:element ref="comment" minOccurs="0"/> <xsd:element name="shipDate" type="xsd:date" minOccurs="0"/> </xsd:sequence> <xsd:attribute name="partNum" type="SKU" use="required"/> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType>

<!-- Stock Keeping Unit, a code for identifying products --> <xsd:simpleType name="SKU"> <xsd:restriction base="xsd:string"> <xsd:pattern value="\d{3}-[A-Z]{2}"/> </xsd:restriction> </xsd:simpleType>

</xsd:schema>

Page 93: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

93Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> is the XML Schemanamespace;• annotation gives info for human readers: <xsd:annotation> <xsd:documentation xml:lang="en"> Purchase order schema for Example.com. Copyright 2000 Example.com. All rights reserved. </xsd:documentation> </xsd:annotation>

• complex type example (“sequence” Cfr. later) : <xsd:complexType name="USAddress"> <xsd:sequence> <xsd:element name="name" type="xsd:string"/> <xsd:element name="street" type="xsd:string"/> <xsd:element name="city" type="xsd:string"/> <xsd:element name="state" type="xsd:string"/> <xsd:element name="zip" type="xsd:decimal"/> </xsd:sequence> <xsd:attribute name="country" type="xsd:NMTOKEN"/> </xsd:complexType>

This is an XML element with 2 subelements. It specifies the type ‘USAddress’. All elements in theInstance document with type “USAddress’ must have a value ‘satisfying’ this type declaration.

• must have 5 subelements in the specified order;• may have a ‘country’ attribute;

Page 94: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

94Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<xsd:element ref="comment" minOccurs="0"/>

References an existing element ‘comment’ that must be declared as a global element (ie. childrenof the <schema> element). Theremay be comment element in the instance document (minOccurs=“0”).

• <xsd:element> has attributes name, type, ref, minOccurs, maxOccurs;

• minOccurs is a nonnegative integer, maxOccurs is a nonnegative integer or unbounded; their default value is 1;• <xsd:attribute> has attributes name, type, use;

• use is “required” or “optional”;default optional <xsd:attribute name="partNum" type="SKU" use="required"/>

Page 95: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

95Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Simple Types

• Built-in XML simple types: “string”, “byte”, “integer”, “long”, “decimal”, “float”, “double”, “boolean”, “dateTime”, “ID”, “IDREF”, “IDREFS”, “anyType”, …

“anyType” is the universal type;

• Restriction of built-in simple types

<xsd:simpleType name="myInteger"> <xsd:restriction base="xsd:integer"> <xsd:minInclusive value="10000"/> <xsd:maxInclusive value="99999"/> </xsd:restriction> </xsd:simpleType>

The element “simple type”” has a subelement “restriction” with two subelements (called facets)

<xsd:simpleType name="SKU"> <xsd:restriction base="xsd:string"> <xsd:pattern value="\d{3}-[A-Z]{2}"/> </xsd:restriction> </xsd:simpleType> Regular expression Cfr. [2]

Page 96: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

96Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<xsd:simpleType name="USState"> <xsd:restriction base="xsd:string"> <xsd:enumeration value="AK"/> <xsd:enumeration value="AL"/> <xsd:enumeration value="AR"/> <!-- and so on ... --> </xsd:restriction> </xsd:simpleType>

Which facets can be combined with which built-in simple types, Cfr. [2].

• List types: lists of built-in simple types or restrictions of built-in simple types

<xsd:simpleType name="listOfMyIntType"> <xsd:list itemType="myInteger"/> </xsd:simpleType>

<listOfMyInt>20003 15037 95977 95945</listOfMyInt> is an element of type“listOfMyIntType”.

Page 97: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

97Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Several facets can be applied to list types: length, minlength, maxlength.

<xsd:simpleType name="USStateList"> <xsd:list itemType="USState"/> </xsd:simpleType>

<xsd:simpleType name="SixUSStates"> <xsd:restriction base="USStateList"> <xsd:length value="6"/> </xsd:restriction> </xsd:simpleType>

<sixStates>PA NY CA NY LA AK</sixStates> is an element of type “SixUSStates”.

Remark that a space delimites the elements of a list. Hence

<a> Paredaens Van Sant </a>

is not an element of type twoNames

<xsd:simpleType name=“stringList"> <xsd:list itemType=“string"/> </xsd:simpleType>

<xsd:simpleType name=“twoNames"> <xsd:restriction base=“stringList"> <xsd:length value=“2"/> </xsd:restriction> </xsd:simpleType>

Page 98: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

98Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• Union typesthe value of elements or attributes with a union type hasa type drawn from the union of multiple built-in types, restrictions or list types.<xsd:simpleType name="myInteger"> <xsd:restriction base="xsd:integer"> <xsd:minInclusive value="10000"/> <xsd:maxInclusive value="99999"/> </xsd:restriction> </xsd:simpleType>

<xsd:simpleType name="USState"> <xsd:restriction base="xsd:string"> <xsd:enumeration value="AK"/> <xsd:enumeration value="AL"/> <xsd:enumeration value="AR"/> <!-- and so on ... --> </xsd:restriction> </xsd:simpleType>

<xsd:simpleType name="zipUnion"> <xsd:union memberTypes="USState listOfMyIntType"/> </xsd:simpleType> <zips>CA</zips> is of type “zipUnion”<zips>95630 95977 95945</zips> is of type “zipUnion”<zips>AK 78997</zips> is NOT of type “zipUnion”<zips>AK CA</zips> is NOT of type “zipUnion”

<xsd:simpleType name=“listOfMyIntType"> <xsd:list itemType=“myInteger"/> </xsd:simpleType>

Page 99: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

99Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Types can be named (and declared separately)or anonymous.

Anonymous Complex Types

• declaring elements with only attributes:

<xsd:element name="internationalPrice"> <xsd:complexType> <xsd:attribute name="currency" type="xsd:string"/> <xsd:attribute name="value" type="xsd:decimal"/> </xsd:complexType> </xsd:element>

<internationalPrice currency="EUR" value="423.46"/> is of the type above.

Complex Types

Page 100: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

100Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• Groups of elements• “sequence”: an ordered set of elements and choices;• “choice”: one element of the given set of elements and sequences;• “all”: an unordered set of elements;• “sequence” within a “choice” and “choice” within a “sequence” can have “minOccurs” and “maxOccurs” attributes.

“sequence”: • can only contain elements or choice-groups;• they have to occur (taking into account

“minOccurs” and “maxOccurs”) in the given order;• “minOccurs” must be nonneg. (default 1), “maxOccurs” must be nonneg. or “unbounded” (default 1)

Page 101: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

101Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<xsd:complexType name="Items"> <xsd:sequence> <xsd:element name=“Item" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:sequence> <xsd:element name="productName" type="xsd:string"/> <xsd:element name="quantity"> <xsd:simpleType> <xsd:restriction base="xsd:positiveInteger"> <xsd:maxExclusive value="100"/> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="USPrice" type="xsd:decimal"/> <xsd:element ref="comment" minOccurs="0"/> <xsd:element name="shipDate" type="xsd:date" minOccurs="0"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType>

Page 102: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

102Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

“choice”: • can only contain elements or sequence-groups;• only at most one can occur (taking into account

“minOccurs” and “maxOccurs”);• “minOccurs” must be nonneg. (default 1), “maxOccurs” must be nonneg. or “unbounded” (default 1)

<xsd:complexType name="PurchaseOrderType"> <xsd:sequence> <xsd:choice> <xsd:sequence minOccurs="0"> <xsd:element name="shipTo" type="USAddress"/> <xsd:element name="billTo" type="USAddress"/> </xsd:sequence> <xsd:element name="singleUSAddress" type="USAddress"/> </xsd:choice> <xsd:element ref="comment" minOccurs="0"/> <xsd:element name=“Items" type="Items"/> </xsd:sequence> <xsd:attribute name="orderDate" type="xsd:date"/> </xsd:complexType>

Page 103: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

103Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

“all”: • can only contain elements;• they occur in an arbitrary order (taking into account

“minOccurs” and “maxOccurs”);• “minOccurs” must be 0 or 1 (default 1), “maxOccurs” must be 1

<xsd:complexType name="PurchaseOrderType"> <xsd:all> <xsd:element name="shipTo" type="USAddress"/> <xsd:element name=“Items" type="Items"/> </xsd:all> </xsd:complexType>

Illegal:<xsd:complexType name="PurchaseOrderType"> <xsd:sequence> <xsd:all> <xsd:element name="shipTo" type="USAddress"/> <xsd:element name=“Items" type="Items"/> </xsd:all> <xsd:sequence> <xsd:element ref="comment" minOccurs="0" maxOccurs="unbounded"/> </xsd:sequence> </xsd:sequence> </xsd:complexType>

Page 104: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

104Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• mixed: allows text appearing between elements and their child elements;

<xsd:element name="letterBody"> <xsd:complexType mixed="true"> <xsd:sequence> <xsd:element name="salutation"> <xsd:complexType mixed="true"> <xsd:sequence> <xsd:element name="name" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="quantity" type="xsd:positiveInteger"/> <xsd:element name="productName" type="xsd:string"/> <xsd:element name="shipDate" type="xsd:date" minOccurs="0"/> <!-- etc. --> </xsd:sequence> </xsd:complexType> </xsd:element>

<letterBody> <salutation>Dear Mr.<name>Robert Smith</name>.</salutation> Your order of <quantity>1</quantity> <productName>Baby Monitor</productName> shipped from our warehouse on <shipDate>2004-12-21</shipDate>. .... </letterBody> is declared in the way above.

Page 105: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

105Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• General form of an anonymous complex type

<complexType name=“…” mixed=“…”> (choice|all|sequence) (<attribute … >)*</complexType>

<xsd:complexType name="PurchaseOrderType"> <xsd:all> <xsd:element name="shipTo" type="USAddress"/> <xsd:element name="billTo" type="USAddress"/> </xsd:all> <xsd:attribute name="orderDate" type="xsd:date"/> </xsd:complexType>

<purchaseOrder orderDate=“2004-04-29"> <billTo> … </billTo> <shipTo> … </shipTo></purchaseOrder> is of the type above.

Page 106: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

106Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Named Types and Groups

<xsd:complexType name="PurchaseOrderType"> <xsd:sequence> <xsd:choice> <xsd:group ref="shipAndBill"/> <xsd:element name="singleUSAddress" type="USAddress"/> </xsd:choice> <xsd:element ref="comment" minOccurs="0"/> <xsd:element name=“Items" type="Items"/> </xsd:sequence> <xsd:attribute name="orderDate" type="xsd:date"/> </xsd:complexType>

<xsd:group name="shipAndBill"> <xsd:sequence> <xsd:element name="shipTo" type="USAddress"/> <xsd:element name="billTo" type="USAddress"/> </xsd:sequence> </xsd:group>

<xsd:complexType name="Items"> <xsd:sequence> … </xsd:sequence> </xsd:complexType>

Page 107: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

107Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

XML Schema and Namespaces

• An XML schema-document starts with the declaration of namespaces :– http://www.w3.org/2001/XMLSchema

• gives the names of the tags, attributes, types in the schema-document

• ex.: schema, attribute, element, …– target namespace

• gives the names defined by the schema-document• ex.: CrsTaken, Student, Status, …

Page 108: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

108Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<schema xmlns=“http://www.w3.org/2001/XMLSchema”

xmlns:po=“http://www.example.com/PO1”

targetNamespace=“http://www.example.com/PO1”>

<element name="purchaseOrder" type=“po:PurchaseOrderType"/> <element name="comment" type="string"/>

<complexType name="PurchaseOrderType"> <sequence> <element name="shipTo" type=“po:USAddress"/> <element name="billTo" type=“po:USAddress"/> <element ref=“po:comment" minOccurs="0"/> <element name=“Items" type="Items"/> </sequence> <attribute name="orderDate" type="date"/> </complexType>

<complexType name="USAddress"> <sequence> <element name="name" type="string"/> <element name="street" type="string"/> <element name="city" type="string"/> <element name="state" type="string"/> <element name="zip" type="decimal"/> </sequence> <attribute name="country" type="NMTOKEN"/> </complexType>

…</schema>

running example 3

Page 109: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

109Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<?xml version="1.0"?><apo:purchaseOrder xmlns:apo=“http://www.example.com/PO1” orderDate=“2004-10-20"> <shipTo country="US"> <name>Alice Smith</name> <street>123 Maple Street</street> <city>Mill Valley</city> <state>CA</state> <zip>90952</zip> </shipTo> <billTo country="US"> <name>Robert Smith</name> <street>8 Oak Avenue</street> <city>Old Town</city> <state>PA</state> <zip>95819</zip> </billTo> <apo:comment>Hurry, my lawn is going wild!</apo:comment> <Items> <Item partNum="872-AA"> <productName>Lawnmower</productName> <quantity>1</quantity> <USPrice>148.95</USPrice> <comment>Confirm this is electric</comment> </Item> <Item partNum="926-AA"> <productName>Baby Monitor</productName> <quantity>1</quantity> <USPrice>39.98</USPrice> <shipDate>2004-12-21</shipDate> <Item> </Items> </apo:purchaseOrder>

running example 3

• In the corresponding XML

instance-documents we

first declare the target

namespace of the schema

Page 110: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

110Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Key - Refkey<xs:element name="vehicle"> <xs:complexType> . . . <xs:attribute name="plateNumber" type="xs:integer"/> <xs:attribute name="state" type="twoLetterCode"/> </xs:complexType> </xs:element> <xs:element name="state"> <xs:complexType> <xs:sequence> <xs:element name="code" type="twoLetterCode"/> <xs:element ref="vehicle" maxOccurs="unbounded"/> <xs:element ref="person" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:key name="reg"> <!-- vehicles are keyed by their plate within states --> <xs:selector xpath=".//vehicle"/> <xs:field xpath="@plateNumber"/> </xs:key> </xs:element> <xs:element name="root"> <xs:complexType> <xs:sequence> . . . <xs:element ref="state" maxOccurs="unbounded"/> . . . </xs:sequence> </xs:complexType>

Page 111: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

111Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<xs:key name="state"> <!-- states are keyed by their code --> <xs:selector xpath=".//state"/> <xs:field xpath="code"/> </xs:key> <xs:keyref name="vehicleState" refer="state"> <!-- every vehicle refers to its state --> <xs:selector xpath=".//vehicle"/> <xs:field xpath="@state"/> </xs:keyref> <xs:key name="regKey"> <!-- vehicles are keyed by a pair of state and plate --> <xs:selector xpath=".//vehicle"/> <xs:field xpath="@state"/> <xs:field xpath="@plateNumber"/> </xs:key> <xs:keyref name="carRef" refer="regKey"> <!-- people's cars are a reference --> <xs:selector xpath=".//car"/> <xs:field xpath="@regState"/> <xs:field xpath="@regPlate"/> </xs:keyref> </xs:element> <xs:element name="person"> <xs:complexType> <xs:sequence> . . . <xs:element name="car"> <xs:complexType> <xs:attribute name="regState" type="twoLetterCode"/> <xs:attribute name="regPlate" type="xs:integer"/>

</xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element>

Page 112: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

112Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Each state, within the document, has a different code child value: <xs:key name="state"> <!-- states are keyed by their code --> <xs:selector xpath=".//state"/> <xs:field xpath="code"/> </xs:key>

element information item: <root>target node set: <state>-elements within the <root>-elementkey-sequence: for each such state, its <code>-child value

The selector, with the element information item as the context node, evaluates to a node-set. Call this the target node set. For each node in the target node set all of the fields, with that node as the context node, evaluate to exactly one member, which must have a simple type. Call the sequence of values of the element and/or attribute information items in those node-sets in order the key-sequence of the node.

Key. No two members of the target node set have key- sequences whose members are pairwise equal.

Page 113: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

113Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Each vehicle within the document has a different state-platenumber pair: <xs:key name="regKey"> <!-- vehicles are keyed by a pair of state and plate --> <xs:selector xpath=".//vehicle"/> <xs:field xpath="@state"/> <xs:field xpath="@plateNumber"/> </xs:key>

element information item: <root>target node set: <vehicle>-elements within the <root>-elementkey-sequence: for each such vehicle, its “state” and “plateNumber” attribute value

Each vehicle has a different platenumber attrib. valuewithin each state: <xs:key name="reg"> <!-- vehicles are keyed by their plate within states --> <xs:selector xpath=".//vehicle"/> <xs:field xpath="@plateNumber"/> </xs:key>

element information item: <state>target node set: <vehicle>-elements within the <state>-elementkey-sequence: for each such vehicle, its “plateNumber” attribute value

Page 114: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

114Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Each state attribute value of a vehicle within the document must be the code value of a state within the document: <xs:keyref name="vehicleState" refer="state"> <!-- every vehicle refers to its state --> <xs:selector xpath=".//vehicle"/> <xs:field xpath="@state"/> </xs:keyref>

element information item: <root>referenced key: “state”target node set: <vehicle>-elements within the <root>-elementkey-sequence: for each such vehicle, its “state” attribute valuetarget node set of “state” : <state>-elements within the <root>-element key-sequence: for each such state, its <code>-child value

Keyref.For each member m of the target node set, there must be a member mr in the target set of the referenced key with key-sequence of m = key-sequence of mr.

Page 115: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

115Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Each (regState attribute, regPlate attribute) value of a car within the document, must be a (state attribute, plateNumber attribute) value of a car within the document:

<xs:keyref name="carRef" refer="regKey"> <!-- people's cars are a reference --> <xs:selector xpath=".//car"/> <xs:field xpath="@regState"/> <xs:field xpath="@regPlate"/> </xs:keyref>

element information item: <root>referenced key: “regKey”target node set: <car>-elements within the <root>-elementkey-sequence: for each such car, its “regState” and “regPlate” attribute valuetarget node set of “regKey” : <vehicle>-elements within the <root>-element key-sequence: for each such vehicle, its “state” and “plateNumber” attribute value

Page 116: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

116Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Running Example 2

<schema xmlns=“http://www.w3.org/2001/XMLSchema” xmlns:adm=“http://xyz.edu/Admin” targetNamespace=“http://xyz.edu/Admin”>

<element name=“Report” type=“adm:reportType”/> <complexType name=“reportType”> <sequence> <element name=“Students” type=“adm:studentList”/> <element name=“Classes”> <complexType> <sequence> <element name=“Class” type=“adm:classType” minOccurs=“0” maxOccurs=“unbounded”/> </sequence> </complexType> </element> <element name=“Courses” type=“adm:courseCatalog”/> </sequence> <attribute name=“Date” type=“date”/> </complexType>

Page 117: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

117Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<key name=“PrimaryKeyForClass”> <selector xpath=“Classes/Class”/> <field xpath=“@CrsCode”/> <field xpath=“@Semester”/> </key> <keyref name=“NoBogusTranscripts” refer=“adm:PrimaryKeyForClass”> <selector xpath=“Students/Student/CrsTaken”/> <field xpath=“@CrsCode”/> <field xpath=“@Semester”/> </keyref>

<complexType name=“studentList”> <sequence> <element name=“Student” type=“adm:studentType” minOccurs=“0” maxOccurs=“unbounded”/> </sequence> </complexType> <complexType name=“studentType”> <sequence> <element name=“Name” type=“adm:personNameType”/> <element name=“Status” type=“adm:studentStatus”/> <element name=“CrsTaken” type=“adm:courseTakenType” minOccurs=“0” maxOccurs=“unbounded”/> </sequence> <attribute name=“StudId” type=“adm:studentId”/> </complexType>

Page 118: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

118Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<complexType name=“personNameType”> <sequence> <element name=“First” type=“string”/> <element name=“Last” type=“string”/> </sequence></complexType>

<simpleType name=“studentStatus”> <restriction base=“string”> <enumeration value=“Ul”/> … <enumeration value=“G5”/> </restriction></simpleType>

<complexType name=“courseTakenType”> <attribute name=“CrsCode” type=“adm:courseRef”/> <attribute name=“Semester” type=“string”/></complexType>

<simpleType name=“courseRef”> <restriction base=“IDREF”> <pattern value=“[A-Z]{3}[0-9]{3}”/> </restriction></simpleType>

Page 119: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

119Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<simpleType name=“studentId”>

<restriction base=“ID”>

<pattern value=“[0-9]{9}”/>

</restriction>

</simpleType>

<complexType name=“classType”>

<sequence>

<element name=“CrsCode” type=“adm:courseCode”/>

<element name=“Semester” type=“string”/>

<element name=“ClassRoster” type=“adm:classListType”/>

</sequence>

</complexType>

<complexType name=“classListType”>

<attribute name=“Members” type=“adm:studentIds”/>

</complexType>

<simpleType name=“studentIds”>

<list itemType=“adm:studentRef”/>

</simpleType>

Page 120: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

120Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<simpleType name=“studentRef”> <restriction base=“IDREF”> <pattern value=“[0-9]{9}”/> </restriction> </simpleType>

<complexType name=“courseCatalog”> <sequence> <element name=“Course” type=“adm:courseType” minOccurs=“0” maxOccurs=“unbounded”/> </sequence> </complexType> <complexType name=“courseType”> <sequence> <element name=“Name” type=“string”/> </sequence> <attribute name=“CrsCode” type=“adm:courseCode”/> </complexType> <simpleType name=“courseCode”> <restriction base=“ID”> <pattern value=“[A-Z]{3}[0-9]{3}”/> </restriction> </simpleType></schema>

Page 121: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

121Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<element name=“El”> <complexType> <all> <element name=“E2”> <complexType> <sequence> <element name=“E3”> <complexType> <sequence> <element name=“E4”> <complexType> <sequence> <element name=“E5” type=“string”/> </sequence> <attribute name=“A” type=“string”/> </complexType> </element> <element name=“E6” type=“string”/> <element name=“E7”> <complexType> <all> <element name=“E8” type=“string”

maxOccurs="unbounded"/> </all> </complexType> </element>

</sequence> </complexType> </element> </sequence> </complexType> </element> </all> </complexType><element> 

Abstract Example

Page 122: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

122Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

E1 { E2 < E3 < E4 A < E5 String > E6 String E7 { E8 String } > > }The following are legal key declarations of E1

<key name=“K1”> <selector xpath=“E2/E3”/> <field xpath=“E4/@A”/> <field xpath=“E6”/></key>

<key name=“K2”> <selector xpath=“E2/E3/E4”/> <field xpath=“E5”/></key>

<key name=“K3”> <selector xpath=“E2/E3”/> <field xpath=“E4/E5”/></key>

The following are illegal key declarations of E1

<key name=“K4”> <selector xpath=“E2/E3”/> <field xpath=“E7/E8”/> not one member</key>

<key name=“K5”> <selector xpath=“E2”/> <field xpath=“E3”/></key> the value of E3 has no simple type

<key name=“K6”> <selector xpath=“E3”/> <field xpath=“E4/E5”/></key> the selector-path does not start in E1

<key name=“K7”> <selector xpath=“E2”/> <field xpath=“E4/E5”/></key> the field-path does not start in E2

Page 123: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

123Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

E1 { E2 < E3 < E4 A < E5 String >

E6 String

E7 { E8 String }

>

>

}

The following are legal foreign key

declarations of E1

<keyref name=“KR1” refer=“K2”>

<selector xpath=“E2/E3/E4”/>

<field xpath=“@A”/>

</keyref>

<keyref name=“KR2” refer=“K2”>

<selector xpath=“E2/E3”/>

<field xpath=“E6”/>

</keyref>

<keyref name=“KR3” refer=“K2”>

<selector xpath=“E2/E3/E7”/>

<field xpath=“E8”/>

</keyref>

The following are illegal foreign key declarations of E1

<keyref name=“KR4” refer=“K2”>

<selector xpath=“E2”/>

<field xpath=“E3/E4”/>

</keyref> E4 has no simple type

<keyref name=“KR5” refer=“K2”>

<selector xpath=“E2”/>

<field xpath=“E6”/>

</keyref> the field-path does not start in E2

Page 124: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

124Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

9 Light XQuery

• Concise backwards compatible sublanguage of XQuery• Complete formal description in a couple of pages

• More info at: http://www.adrem.ua.ac.be/~lixquery

Page 125: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

125Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

9 XSLT

• eXtensible Stylesheet Language Transformations;• XSLT is a stylesheet language;• Mainly used to translate XML into HTML;• Turing Complete;• Templates (procedures) are central;• Templates can have (input) parameters;• Templates write on a variable or on the output;• Templates are called or ‘match’;• An XSLT stylesheet is an XML document;• Uses namespaces;• Syntax is influenced by stylesheet people;

Page 126: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

126Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Syntax van MiXSLT

Page 127: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

127Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Page 128: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

128Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<?xml version="1.0" encoding="UTF-8"?>BUT ROME WASNOT BUILT IN 1 DAY.

<xsl:stylesheet version="2.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"> <xsl:output method = "xml"/>

<xsl:template match = "/">BUT ROME WASNOT BUILT IN 1 DAY.</xsl:template>

</xsl:stylesheet> Output Document

Statements : 1. Text

XSLT-file

Page 129: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

129Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<xsl:stylesheet version="2.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"> <xsl:output method = "xml"/>

<xsl:template match = "/">BUT ROME WAS <xsl:element name="Antwerp"> NOT </xsl:element> <xsl:element name="Antwerp"> JUST <xsl:element name="Antwerp">

</xsl:element> COULD </xsl:element>NOT BUILT IN <xsl:element name="Antwerp"> </xsl:element> 1 DAY.</xsl:template>

</xsl:stylesheet>

<?xml version="1.0" encoding="UTF-8"?>BUT ROME WAS <Antwerp> NOT </Antwerp><Antwerp> JUST <Antwerp/> COULD </Antwerp>NOT BUILT IN <Antwerp/> 1 DAY.

Remark the blanc space!

<xsl:element name=“AA”> … </xsl:element> <AA> …</AA>

2. Element

Page 130: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

130Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<?xml version="1.0"?><a> <b>Ma </b> <a> <b> <c>Roma </c> <c>non </c> </b> <a> <c i="Giovanni">fu </c> <c>fatta </c> </a> <b> <c>in </c> <c>un </c> </b> </a> <b>giorno.</b></a>

<xsl:stylesheet version="2.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"> <xsl:output method = "xml"/>

<xsl:template match = "/"> <xsl:value-of select="*/a/b/c[2]"/> <xsl:value-of select="*/a/b/c[2]/text()"/> <xsl:value-of select="*/a/a[1]/c/@i"/> <xsl:value-of select="name(*/*[3])"/></xsl:template>

</xsl:stylesheet>

<?xml version="1.0" encoding="UTF-8"?>non un non un Giovannib

Input Document 3. Value-of

Page 131: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

131Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

The xsl:value-of element is instantiated to create a text node in the result tree. The required select attribute is an XPath-expression; this expression is evaluated and the resulting object is converted to a string as if by a call to the string function. The string specifies the string-value of the created text node. If the string is empty, no text node will be created. The created text node will be merged with any adjacent text nodes.

Page 132: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

132Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

4. Copy-of

<?xml version="1.0"?><a> <b>Ma </b> <a> <b> <c>Roma </c> <c>non </c> </b> <a> <c i="Giovanni">fu </c> <c>fatta </c> </a> <b> <c>in </c> <c>un </c> </b> </a> <b>giorno.</b></a>

<xsl:stylesheet version="2.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"> <xsl:output method = "xml"/>

<xsl:template match = "/"> <xsl:copy-of select="*/a/b/c[2]"/> <xsl:copy-of select="*/a/b/c[2]/text()"/> <a> <xsl:copy-of select="*/a/a[1]/c/@i"/> </a> <xsl:copy-of select="name(*/*[3])"/> <xsl:copy-of select="123"/></xsl:template>

</xsl:stylesheet>

<?xml version="1.0" encoding="UTF-8"?><c>non </c><c>un </c>non un <a i="Giovanni"/>b 123

Page 133: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

133Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

The xsl:copy-of element can be used to insert a result treefragment into the result tree, without first converting it to a string as xsl:value-of does. The required select attribute contains an expression. When the result of evaluating the expression is a result tree fragment, the complete fragment is copied into the result tree. When the result is a node-set, all the nodes in the set are copied in document order into the result tree; copying an element node copies the attribute nodes and children of the element node as well as the element node itself; a root node is copied by copying its children. When the result is neither a node-set nor a result tree fragment, the result is converted to a string and then inserted into the result tree, as with xsl:value-of.

Page 134: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

134Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

5. For-each

<?xml version="1.0"?><a> <b>Ma </b> <a> <b> <c>Roma </c> <c>non </c> </b> <a> <c i="Giovanni">fu </c> <c>fatta </c> </a> <b> <c>in </c> <c>un </c> </b> </a> <b>giorno.</b></a>

<xsl:stylesheet version="2.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"> <xsl:output method = "xml"/>

<xsl:template match = "/"> <xsl:element name="{name(*/*[3])}"> <xsl:for-each select="//*"> <xsl:value-of select="name(.)"/> </xsl:for-each>AA <xsl:for-each select="*/*,*"> BB <xsl:value-of select="."/> </xsl:for-each> </xsl:element></xsl:template>

</xsl:stylesheet>

<?xml version="1.0" encoding="UTF-8"?><b>ababccaccbccbAA BB Ma BB Roma non fu fatta in un BB giorno. BB Ma Roma non fu fatta in un giorno.</b>

• Current node!

Page 135: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

135Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

The xsl:for-each instruction contains a template, which is instantiated for each node selected by the expression specified by the select attribute. The select attribute is required. The expression must evaluate to a node-set. The template is instantiated with the selected node as the current node, and with a list of all of the selected nodes as the current node list.

Page 136: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

136Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

6. Copy

<?xml version="1.0"?><a> <b>Ma </b> <a> <b> <c>Roma </c> <c>non </c> </b> <a> <c i="Giovanni">fu </c> <c>fatta </c> </a> <b> <c>in </c> <c>un </c> </b> </a> <b>giorno.</b></a>

<xsl:stylesheet version="2.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"> <xsl:output method = "xml"/>

<xsl:template match = "/"> <xsl:for-each select="*/*"> <xsl:copy> <xsl:for-each select="*"> <xsl:copy/> </xsl:for-each> </xsl:copy> </xsl:for-each>-- <xsl:for-each select="*"> <xsl:copy> <xsl:for-each select="*"> <xsl:copy/> </xsl:for-each> </xsl:copy> </xsl:for-each></xsl:template>

</xsl:stylesheet>

<?xml version="1.0" encoding="UTF-8"?><b/><a><b/><a/><b/></a><b/>-- <a><b/><a/><b/></a>

Page 137: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

137Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

The xsl:copy element provides an easy way of copying the current node. Instantiating the xsl:copy element creates a copy of the current node. The attributes and children of the node are not automatically copied. The content of the xsl:copy element is a template for the attributes and children of the created node; the content is instantiated only for nodes of types that can have attributes or children (i.e. root nodes and element nodes).

Page 138: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

138Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

7. If

• No else• ‘ … ‘ within “ … “• current node!

<?xml version="1.0"?><a> <b>Ma </b> <a> <b> <c>Roma </c> <c>non </c> </b> <a> <c i="Giovanni">fu </c> <c>fatta </c> </a> <b> <c>in </c> <c>un </c> </b> </a> <b>giorno.</b></a>

<xsl:stylesheet version="2.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"> <xsl:output method = "xml"/><xsl:template match = "/"> <xsl:if test="true()"> 123 </xsl:if> <xsl:if test="false()"> 234 </xsl:if> <xsl:if test="'xx'"> 345 </xsl:if> <xsl:if test="''"> 456 </xsl:if> <xsl:if test="0"> 567 </xsl:if> <xsl:if test="23"> 678 </xsl:if> <xsl:if test="*"> 789 </xsl:if> <xsl:if test="c"> 890 </xsl:if> <xsl:if test="*/b"> 901 <xsl:if test="*/b"> 012 </xsl:if> </xsl:if></xsl:template></xsl:stylesheet>

<?xml version="1.0" encoding="UTF-8"?> 123 345 678 789 901 012

Page 139: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

139Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

The xsl:if element has a test attribute, which specifies anXPath-expression. The content is a template. The expression is evaluated and the resulting object is converted to a boolean as if by a call to the boolean function. If the result is true, then the content template is instantiated; otherwise, nothing is created.

Page 140: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

140Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

8. Variable<xsl:stylesheet version="2.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"> <xsl:output method = "xml"/>

<xsl:template match = "/"> <xsl:variable name="x" select ="/a/a"/> <xsl:variable name="y"> 123 <xsl:element name="el"> ABC </xsl:element> </xsl:variable> <xsl:variable name="z"> <xsl:copy-of select="*/*[2]/*[1]"/> </xsl:variable> <xsl:copy-of select="$x"/> <xsl:copy-of select="$y"/> <xsl:copy-of select="$z"/> <xsl:value-of select="$x"/> <xsl:value-of select="$y"/> <xsl:value-of select="$z"/> <xsl:copy-of select="$x/b/c[1]"/> <xsl:copy-of select="$y/*"/> <xsl:copy-of select="$z/*/c[2]"/> </xsl:template>

</xsl:stylesheet>

<?xml version="1.0" encoding="UTF-8"?><a> <b> <c>Roma </c> <c>non </c> </b> <a> <c i="Giovanni">fu </c> <c>fatta </c> </a> <b> <c>in </c> <c>un </c> </b> </a> 123 <el> ABC </el><b> <c>Roma </c> <c>non </c> </b> Roma non fu fatta in un

123 ABC Roma non <c>Roma </c><c>in </c><el> ABC </el><c>non </c>

Page 141: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

141Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<xsl:stylesheet version="2.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"> <xsl:output method = "xml"/>

<xsl:template match = "/"> <xsl:variable name="x" select ="100"/> <xsl:value-of select="$x"/>, <xsl:if test="true()"> <xsl:variable name="x" select ="200"/> <xsl:value-of select="$x"/>, </xsl:if> <xsl:value-of select="$x"/>, <xsl:for-each select="*/*"> <xsl:variable name="x" select ="$x+20"/> <xsl:value-of select="$x"/>, </xsl:for-each> <xsl:value-of select="$x"/>,</xsl:template>

</xsl:stylesheet> <?xml version="1.0" encoding="UTF-8"?>100, 200, 100, 120, 120, 120, 100,

<?xml version="1.0"?><a> <b>Ma </b> <a> <b> <c>Roma </c> <c>non </c> </b> <a> <c i="Giovanni">fu </c> <c>fatta </c> </a> <b> <c>in </c> <c>un </c> </b> </a> <b>giorno.</b></a>

Page 142: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

142Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

A variable is a name that may be bound to a value. For these variable-binding elements, there is a region of the stylesheet tree within which the binding is visible; within this region, any binding of the variable that was visible on the variable-binding element itself is hidden. Thus, only the innermost binding of a variable is visible. The set of variable bindings in scope for an expression consists of those bindings that are visible at the point in the stylesheet where the expression occurs.

Page 143: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

143Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

9. Call-template

<?xml version="1.0"?><a> <b>Ma </b> <a> <b> <c>Roma </c> <c>non </c> </b> <a> <c i="Giovanni">fu </c> <c>fatta </c> </a> <b> <c>in </c> <c>un </c> </b> </a> <b>giorno.</b></a>

<xsl:stylesheet version="2.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"> <xsl:output method = "xml"/>

<xsl:template match = "/">CCDD <xsl:call-template name="Temp1"/>EEFF <xsl:call-template name="Temp2"/>GGHH <xsl:copy-of select="*/*[1]"/></xsl:template>

<xsl:template name="Temp1">AABB</xsl:template>

<xsl:template name="Temp2"> <xsl:copy-of select="*/*[1]"/></xsl:template>

</xsl:stylesheet>

<?xml version="1.0" encoding="UTF-8"?>CCDD AABB

EEFF <b>Ma </b>GGHH <b>Ma </b>

Page 144: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

144Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Templates can be invoked by name. An xsl:template element with a name attribute specifies a named template. An xsl:call-template element invokes a template by name; it has a required name attribute that identifies the template to be invoked. An xsl:call-template does not change the current node nor the current node list.

Page 145: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

145Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

10. Parameters<?xml version="1.0"?><a> <b>Ma </b> <a> <b> <c>Roma </c> <c>non </c> </b> <a> <c i="Giovanni">fu </c> <c>fatta </c> </a> <b> <c>in </c> <c>un </c> </b> </a> <b>giorno.</b></a>

<xsl:stylesheet version="2.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"> <xsl:output method = "xml"/>

<xsl:template match = "/">CCDD <xsl:call-template name="Temp1"/>GGHH <xsl:call-template name="Temp1"> <xsl:with-param name="p1" select="*/b[1]"/> </xsl:call-template>EEFF <xsl:call-template name="Temp1"> <xsl:with-param name="p1" select="*/b[2]"/> <xsl:with-param name="p2"> <Bob> <Tim/> </Bob> </xsl:with-param> </xsl:call-template>MMNN</xsl:template>

<xsl:template name="Temp1"> <xsl:param name="p1"/> <xsl:param name="p2"/> <xsl:value-of select="name(*)"/> <xsl:copy-of select="$p1"/>OOPP <xsl:copy-of select="$p2"/></xsl:template>

</xsl:stylesheet>

<?xml version="1.0" ...CCDD aOOPP GGHH a<b>Ma </b>OOPP EEFF a<b>giorno.</b>OOPP <Bob><Tim/></Bob>MMNN

Page 146: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

146Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

A parameter is a name that may be bound to a value. Parameters are passed to templates using the xsl:with-param element. The required name attribute specifies the name of the parameter. Every parameter in an xsl:with-param has to be declared by anxsl:param in the called template.The value of the parameter is specified in xsl:with-param in the same way as in xsl:variable.The current node and current node list used for computing the value specified by xsl:with-param element is the same as that used for the xsl:apply-templates or xsl:call-template element within which it occurs. It is not an error to pass a parameter x to a template that does not have an xsl:param element for x; the parameter is simply ignored.The parameters are only visible within the template in which they are declared.

Page 147: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

147Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

• Global product• Cannot be done by a for-each

<xsl:stylesheet version="2.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"> <xsl:output method = "xml"/><xsl:template match = "/"> <xsl:variable name="list"> <e i="6"/> <e i="2"/> <e i="3"/> <e i="2"/> <e i="4"/> </xsl:variable> <xsl:call-template name="Product"> <xsl:with-param name="parlist"> <xsl:copy-of select="$list/*"/> </xsl:with-param> <xsl:with-param name="parprod" select="1"/> </xsl:call-template></xsl:template>

<xsl:template name="Product"> <xsl:param name="parlist"/> <xsl:param name="parprod"/> <xsl:if test="$parlist/*[1]"> <xsl:call-template name="Product"> <xsl:with-param name="parlist"> <xsl:copy-of select="$parlist/*[position()>1]"/> </xsl:with-param> <xsl:with-param name="parprod" select="$parprod*$parlist/*[1]/@i"/> </xsl:call-template> </xsl:if> <xsl:if test="not($parlist/*[1])"> <xsl:value-of select="$parprod"/> </xsl:if></xsl:template></xsl:stylesheet>

<?xml version="1.0" encoding="UTF-8"?>288

Page 148: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

148Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

11. Template - Apply-templates

<?xml version="1.0"?><b key=" k1"> <a key=" k2"> <a key=" k3"> <b key=" k4"> M4M </b> </a> <b key=" k5"> <a key=" k6"> M7M </a> </b> </a> <b key=" k7"> M6M </b> <a key=" k8"> <a key=" k9"> M8M </a> </a></b>

<xsl:stylesheet version="2.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"> <xsl:output method = "xml"/>

<xsl:template match = "/"> <xsl:apply-templates select="*/*"/></xsl:template>

<xsl:template match="b"> <xsl:value-of select="@key"/>NN</xsl:template>

</xsl:stylesheet>

<?xml version="1.0" encoding="UTF-8"?> k4NN

k5NN

k7NN

M8M

Page 149: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

149Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

A template has a name-attribute or a match-attribute.Those with a name are called with call-template. The others are called with apply-templates.The value of the match-attribute of a template is a pattern p. It indicates that the template can only be called for nodes n for which there is a node n’ such that n belongs to the sequence that results from the application of p to n’. It is an error for the value of the match attribute to contain a variable. The content of the template element is instantiated when the template is called.

Page 150: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

150Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

The value of the select attribute of apply-templates is an XPath-expression. The expression must evaluate to a node-set. This set is processed in document order. To process a node n means that n becomes the current node and that a template with a match-attribute is called for n. If no such template exists, all the children of n are processed in document order, if n is not a leaf.If n is a leaf its content is instantiated. If more such templates exist, the template with the highest priority is selected. The default priority is 0. If more then one template has the highest priority there is an ambiguity.

If the apply-template has a mode-attribute, only templates are called with a mode-attribute with the same value. If the apply-template does not have a mode-attribute, only templates are called with no mode-attribute.

Page 151: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

151Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<?xml version="1.0"?><b key=" k1"> <a key=" k2"> <a key=" k3"> <b key=" k4"> M4M </b> </a> <b key=" k5"> <a key=" k6"> M7M </a> </b> </a> <b key=" k7"> M6M </b> <a key=" k8"> <a key=" k9"> M8M </a> </a></b>

<xsl:stylesheet version="2.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"> <xsl:output method = "xml"/>

<xsl:template match = "/"> <xsl:apply-templates select="*/*"/> <xsl:apply-templates select="*/*" mode="M"/></xsl:template>

<xsl:template match="b"> <xsl:value-of select="@key"/>NN</xsl:template>

<xsl:template match="b/b" priority="1"> <xsl:value-of select="@key"/>LL</xsl:template>

<xsl:template match="a" mode="M"> <xsl:value-of select="@key"/>KK</xsl:template>

</xsl:stylesheet>

<?xml version="1.0" encoding="UTF-8"?> k4NN

k5NN

k7LL

M8M k2KK

M6M k8KK

Page 152: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

152Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<?xml version="1.0"?><a> <b>Ma </b> <a> <b> <c>Roma </c> <c>non </c> </b> <a> <c i="Giovanni">fu </c> <c>fatta </c> </a> <b> <c>in </c> <c>un </c> </b> </a> <b>giorno.</b></a>

<xsl:stylesheet version="2.0" xmlns:xsl = "http://..."> <xsl:output method = "xml"/>

<xsl:template match = "/"> <xsl:apply-templates select="//*"/></xsl:template>

<xsl:template match="*"> <xsl:choose> <xsl:when test="name()='a'"> AA </xsl:when> <xsl:when test="name()='b'"> BB </xsl:when> <xsl:otherwise> CC </xsl:otherwise> </xsl:choose></xsl:template>

</xsl:stylesheet>

<?xml version="1.0" …?> AA BB AA BB CC CC AA CC CC BB CC CC BB

12. Choose – when - otherwise

Page 153: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

153Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

The xsl:choose element selects one among a number of possible alternatives. It consists of a sequence of xsl:when elements followed by an optional xsl:otherwise element. Each xsl:when element has a single attribute, test, which specifies an expression. The content of the xsl:when and xsl:otherwise elements is a template. When an xsl:choose element is processed, each of the xsl:when elements is tested in turn, by evaluating the expression and converting the resulting object to a boolean as if by a call to the boolean function. The content of the first, and only the first, xsl:when element whose test is true is instantiated. If no xsl:when is true, the content of the xsl:otherwise element is instantiated. If no xsl:when element is true, and no xsl:otherwise element is present, nothing is created.

Page 154: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

154Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

13. Key<?xml version="1.0"?><a> <b>Ma </b> <a> <b> <c>un </c> <c>Roma </c> <c>non </c> <c i="jan">si </c> <c>un </c> <c>uno </c> <c>noon </c> </b> <a> <c i="Giovanni">fu </c> <c>un </c> <c>non </c> <c>fatta </c> </a> <b> <c>in </c> <c>un </c> <c>uni </c> <c>non </c> <c>un </c> <c>si </c> <c>un </c> </b> </a> <b>giorno.</b></a>

<xsl:stylesheet version="2.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"> <xsl:output method = "xml"/>

<xsl:key name="go" match="c" use="following-sibling::*[1]"/><xsl:key name="goo" match="c" use="following-sibling::*"/><xsl:key name="gi" match="c" use="@i"/>

<xsl:template match = "/"> <a> <xsl:apply-templates select="key('go','uno ')"/>CC <xsl:apply-templates select="key('go',(/*/*/*/*)[6])"/>DD <xsl:apply-templates select="key('goo','non ')"/>EE <xsl:apply-templates select="key('gi','jan')"/>FF <xsl:apply-templates select="key('gi',(/*/*/*/*)[4]/@i)"/>GG <xsl:apply-templates select="key('gi',(/*/*/*/*)/@i)"/>HH <xsl:apply-templates select="key('goo',(/*/*/*/*) [position() &gt;= 3 and position() &lt;= 4])"/>II </a></xsl:template>

<xsl:template match="*"> AA<xsl:value-of select="."/>BB</xsl:template>

</xsl:stylesheet

Page 155: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

155Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<?xml version="1.0" encoding="UTF-8"?><a> AAun BB

CC AAun BB

DD AAun BB

AARoma BB

AAfu BB

AAun BB

AAin BB

AAun BB

AAuni BB

EE AAsi BB

FF AAsi BB

GG AAsi BB

AAfu BB

HH AAun BB

AARoma BB

AAnon BB

AAfu BB

AAun BB

AAin BB

AAun BB

AAuni BB

AAnon BB

AAun BB

II

Page 156: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

156Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

The xsl:key element is used to declare keys. The name attribute specifies the name of the key. The match attribute is a Pattern; the use attribute is an expression specifying the values of the key; the expression is evaluated once for each node that matches the pattern. It is an error for the value of either the use attribute or the match attribute to contain a VariableReference.

The first argument of the key function specifies the name of the key. The value of the argument must be a name. The second argument is converted to a set of strings; the key function returns a node-set containing the nodes in the same document as the context node that have a value for the named key equal to one of these strings.

Page 157: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

157Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

Examples1. Composition

<!– RenAtoC calculates the renaming (A->C)of R in Tables.in.xml. -->

<xsl:stylesheet version="2.0" xmlns:xsl = “…"> <xsl:output method = "xml"/>

<xsl:template match="/"> <Renaming_of_R> <xsl:apply-templates select="//R/*"/> </Renaming_of_R> </xsl:template>

<xsl:template match="*"> <tuple> <xsl:for-each select="@*"> <xsl:if test="name()='A'"> <xsl:attribute name="C" select="."/> </xsl:if> <xsl:if test="name()!='A'"> <xsl:attribute name="{name()}" select="."/> </xsl:if> </xsl:for-each> </tuple></xsl:template>

</xsl:stylesheet>

<!– RenBtoD calculates the renaming (B->D) of T in Tables.in.xml. -->

<xsl:stylesheet version="2.0" xmlns:xsl = “…"> <xsl:output method = "xml"/>

<xsl:template match="/"> <Renaming_of_T> <xsl:apply-templates select="//T/*"/> </Renaming_of_T> </xsl:template>

<xsl:template match="*"> <tuple> <xsl:for-each select="@*"> <xsl:if test="name()='B'"> <xsl:attribute name="D" select="."/> </xsl:if> <xsl:if test="name()!='B'"> <xsl:attribute name="{name()}" select="."/> </xsl:if> </xsl:for-each> </tuple></xsl:template>

</xsl:stylesheet>

Page 158: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

158Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<!-- Composes RenAtoC followed by RenBtoD. This composition is applied to R in Tables.in.xml. -->

<xsl:stylesheet version="2.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"> <xsl:output method = "xml"/>

<xsl:template match="/"> <xsl:variable name="ResultOfRenAtoC"> <xsl:apply-templates select="//R/*" mode="m1"/> </xsl:variable> <Result> <xsl:apply-templates select="$ResultOfRenAtoC/*" mode="m2"/> </Result> </xsl:template>

<xsl:template match="*" mode="m1"> <tuple> <xsl:for-each select="@*"> <xsl:if test="name()='A'"> <xsl:attribute name="C" select="."/> </xsl:if> <xsl:if test="name()!='A'"> <xsl:attribute name="{name()}" select="."/> </xsl:if> </xsl:for-each> </tuple></xsl:template>

<xsl:template match="*" mode="m2"> .<tuple> <xsl:for-each select="@*"> <xsl:if test="name()='B'"> <xsl:attribute name="D" select="."/> </xsl:if> <xsl:if test="name()!='B'"> <xsl:attribute name="{name()}" select="."/> </xsl:if> </xsl:for-each> </tuple></xsl:template>

</xsl:stylesheet>

Page 159: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

159Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<?xml version="1.0" encoding="UTF-8"?><doc> <R> <tuple A="a" B="a"/> <tuple A="a" B="b"/> <tuple A="a" B="c"/> <tuple A="b" B="a"/> <tuple A="b" B="b"/> </R> <S> <tuple A="c" B="a"/> <tuple A="b" B="b"/> <tuple A="c" B="c"/> <tuple A="a" B="a"/> <tuple A="d" B="b"/> </S> <T> <tuple C="c" B="a"/> <tuple C="b" B="b"/> <tuple C="a" B="c"/> <tuple C="a" B="b"/> <tuple C="d" B="b"/> </T> <V> <tuple C="c" D="a"/> <tuple C="b" D="b"/> <tuple C="a" D="c"/> <tuple C="a" D="b"/> <tuple C="d" D="b"/> </V> <U> <tuple B="b"/> <tuple B="a"/> </U></doc>

<?xml version="1.0" encoding="UTF-8"?><Result> .<tuple C="a" D="a"/> .<tuple C="a" D="b"/> .<tuple C="a" D="c"/> .<tuple C="b" D="a"/> .<tuple C="b" D="b"/></Result>

Page 160: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

160Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<!-- The elements of the first tape have to merge, one-by-one, to the elements of the second tape.Merging two elements results in a new element, with the name of the first, the attributes and the subelements of both. The problem is here that we have to consider "two heads". -->

<xsl:stylesheet version="2.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"> <xsl:output method = "xml"/><xsl:variable name="sp">.</xsl:variable><xsl:template match="/"> <doc> <result-tape> <xsl:call-template name="merge"> <xsl:with-param name="first"><xsl:copy-of select="//first-tape/*"/></xsl:with-param> <xsl:with-param name="second"><xsl:copy-of select="//second-tape/*"/></xsl:with-param> </xsl:call-template> </result-tape> </doc></xsl:template><xsl:template name="merge"> <xsl:param name="first"/> <xsl:param name="second"/> <xsl:value-of select="$sp"/> <xsl:element name="{name($first/*[1])}"> <xsl:for-each select="$first/*[1]/@*"> <xsl:attribute name="{name()}" select="."/> </xsl:for-each> <xsl:for-each select="$second/*[1]/@*"> <xsl:attribute name="{name()}" select="."/> </xsl:for-each> <xsl:for-each select="$first/*[1]/*"> <xsl:copy-of select="."/> </xsl:for-each> <xsl:for-each select="$second/*[1]/*"> <xsl:copy-of select="."/> </xsl:for-each> </xsl:element> <xsl:if test="$first/*[2]"> <xsl:call-template name="merge"> <xsl:with-param name="first"><xsl:copy-of select="$first/*[position()>1]"/></xsl:with-param> <xsl:with-param name="second"><xsl:copy-of select="$second/*[position()>1]"/></xsl:with-param> </xsl:call-template> </xsl:if></xsl:template>

</xsl:stylesheet>

2. Two heads

Page 161: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

161Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<?xml version="1.0" encoding="UTF-8"?><doc><result-tape>.<a name1="a1" name2="a2" type="t2"><p name="p1"/><p name="p2"/><p name="p3"/><p name="r3"> <p name="r4"/> </p></a>.<a name="b1" type1="u1" type2="u2"><p name="q1"/><p name="r5"/><p name="r6"/></a>.<a name="c1" type="v2"><p name="r1"/><p name="r2"/><p name="r7"/><p name="r8"/></a></result-tape></doc>

<?xml version="1.0" encoding="UTF-8"?><doc> <first-tape> <a name1="a1" name2="a2"> <p name="p1"/> <p name="p2"/> </a> <a name="b1"> <p name="q1"/> </a> <a name="c1"> <p name="r1"/> <p name="r2"/> </a> </first-tape> <second-tape> <b type="t2"> <p name="p3"/> <p name="r3"> <p name="r4"/> </p> </b> <b type1="u1" type2="u2"> <p name="r5"/> <p name="r6"/> </b> <b type="v2"> <p name="r7"/> <p name="r8"/> </b> </second-tape></doc>

Page 162: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

162Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<!-- Runs in in-order through a binary tree until it sees the element with @i value equal to "172". -->

<xsl:stylesheet version="2.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"> <xsl:output method = "xml"/>

<xsl:template match="/"> <xsl:variable name="future"> <xsl:call-template name="TreeRun"> <xsl:with-param name="RTree" select="/*"/> </xsl:call-template> </xsl:variable> <xsl:copy-of select="$future/a"/></xsl:template>

<xsl:template name="TreeRun"> <xsl:param name="RTree"/> <xsl:if test="$RTree/*"> <xsl:variable name="futurel"> <xsl:call-template name="TreeRun"> <xsl:with-param name="RTree" select="$RTree/left"/> </xsl:call-template> </xsl:variable> <xsl:copy-of select="$futurel/a"/> <xsl:if test="$futurel/stop"> <stop/> </xsl:if> <xsl:if test="not($futurel/stop)"> <xsl:copy-of select="$RTree/a"/>

<xsl:choose> <xsl:when test="$RTree/a/@i='172'"> <stop/> </xsl:when> <xsl:otherwise> <xsl:variable name="futurer"> <xsl:call-template name="TreeRun"> <xsl:with-param name="RTree" select="$RTree/right"/> </xsl:call-template> </xsl:variable> <xsl:copy-of select="$futurer/a"/> <xsl:if test="$futurer/stop"> <stop/> </xsl:if> </xsl:otherwise> </xsl:choose> </xsl:if> </xsl:if></xsl:template>

</xsl:stylesheet>

3. return value of a template

Page 163: 1 Deel II XML © Prof. dr. J. Paredaens 2008 - 2009 DEEL II XML.

163Deel II XML © Prof. dr. J. Paredaens 2008 - 2009

<?xml version="1.0" encoding="UTF-8"?><tree><left> <left> <left> <left/> <a i="3"/> <right/> </left> <a i="183"/> <right/> </left> <a i="1"/> <right> <left/> <a i="128"/> <right/> </right></left><a i="83"/><right> <left> <left> <left> <left/> <a i="73"/> <right/> </left> <a i="46"/>

<right> <left/> <a i="19"/> <right/> </right> </left> <a i="172"/> <right/> </left> <a i="183"/> <right> <left/> <a i="3667"/> <right> <left/> <a i="77"/> <right/> </right> </right></right></tree>

<?xml version="1.0" encoding="UTF-8"?><a i="3"/><a i="183"/><a i="1"/><a i="128"/><a i="83"/><a i="73"/><a i="46"/><a i="19"/><a i="172"/>