Sie sind auf Seite 1von 199

1

XPath 1.0
http://www.w3.org/TR/xquery/

Roger L. Costello
6 March 2010

XPath is not a
standalone language
XML
Schemas

XSLT

XPath

XQuery

XPointer

Schematron
A complete list of technologies that use XPath:
http://expath.org/wiki/Engines

This XML document can be


represented as a tree, as shown below

Document
/

PI
<?xml version=1.0?>

Text
Jeff

Element
FitnessCenter

Element
Member

Element
Member

Element
Name

<?xml version="1.0"?>
<FitnessCenter>
<Member>
<Name>Jeff</Name>
<FavoriteColor>lightgrey</FavoriteColor>
</Member>
<Member>
<Name>David</Name>
<FavoriteColor>lightblue</FavoriteColor>
</Member>
<Member>
<Name>Roger</Name>
<FavoriteColor>lightyellow</FavoriteColor>
</Member>
</FitnessCenter>

Element
FavoriteColor

Text
lightgrey

Element
Name

Text
David

Element
Member

Element
FavoriteColor

Text
lightblue

Element
Name

Text
Roger

Element
FavoriteColor

Text
lightyellow

Terminology: node
Document node

Processing Instruction (PI) node

Element nodes

Document
/

PI
<?xml version=1.0?>

Element
FitnessCenter

Element
Member

Element
Member

Text nodes

Element
Name

Text
Jeff

Element
FavoriteColor

Text
lightgrey

Element
Name

Text
David

Element
Member

Element
FavoriteColor

Text
lightblue

Element
Name

Text
Roger

Element
FavoriteColor

Text
lightyellow

Document
/

PI
<?xml version=1.0?>

With
respect to
this node,
these are
its children
Element
Name

Text
Jeff

Element
FitnessCenter

Element
Member

Element
Member

Element
FavoriteColor

Text
lightgrey

Element
Name

Text
David

Element
Member

Element
FavoriteColor

Text
lightblue

Element
Name

Text
Roger

Element
FavoriteColor

Text
lightyellow

Document
/

PI
<?xml version=1.0?>

These are
its
descendant
nodes

Element
Name

Text
Jeff

Element
FitnessCenter

Element
Member

Element
Member

Element
FavoriteColor

Text
lightgrey

Element
Name

Text
David

Element
Member

Element
FavoriteColor

Text
lightblue

Element
Name

Text
Roger

Element
FavoriteColor

Text
lightyellow

Document
/

PI
<?xml version=1.0?>

This is the
context node

Element
Name

Text
Jeff

Element
FitnessCenter

Element
Member

Element
Member

Element
FavoriteColor

Text
lightgrey

Element
Name

Text
David

Element
Member

Element
FavoriteColor

Text
lightblue

Element
Name

Text
Roger

Element
FavoriteColor

Text
lightyellow

Document
/

PI
<?xml version=1.0?>

Element
Member

Element
Name

Text
Jeff

Element
FitnessCenter

That's
its parent

Element
FavoriteColor

Text
lightgrey

Element
Member

Element
Name

Text
David

Element
Member

Element
FavoriteColor

Text
lightblue

Element
Name

Text
Roger

Element
FavoriteColor

Text
lightyellow

Document
/

PI
<?xml version=1.0?>

Element
Member

Element
Name

Text
Jeff

Element
FitnessCenter

Those are
its
ancestors
Element
FavoriteColor

Text
lightgrey

Element
Member

Element
Name

Text
David

Element
Member

Element
FavoriteColor

Text
lightblue

Element
Name

Text
Roger

Element
FavoriteColor

Text
lightyellow

10

Document
/

PI
<?xml version=1.0?>

Element
Member

Element
Name

Text
Jeff

Element
FitnessCenter

It has 2
siblings

Element
FavoriteColor

Text
lightgrey

Element
Member

Element
Name

Text
David

Element
Member

Element
FavoriteColor

Text
lightblue

Element
Name

Text
Roger

Element
FavoriteColor

Text
lightyellow

11

Document
/

PI
<?xml version=1.0?>

Element
Member

Element
Name

Text
Jeff

Element
FitnessCenter

They are
followingsiblings
Element
FavoriteColor

Text
lightgrey

Element
Member

Element
Name

Text
David

Element
Member

Element
FavoriteColor

Text
lightblue

Element
Name

Text
Roger

Element
FavoriteColor

Text
lightyellow

12

Document
/

PI
<?xml version=1.0?>

Element
Member

Element
Name

Text
Jeff

Element
FitnessCenter

It has no
precedingsiblings
Element
FavoriteColor

Text
lightgrey

Element
Member

Element
Name

Text
David

Element
Member

Element
FavoriteColor

Text
lightblue

Element
Name

Text
Roger

Element
FavoriteColor

Text
lightyellow

13

Here are the


capabilities of XPath
XPath provides a syntax for:

navigating around an XML document


selecting nodes and values
comparing node values
performing arithmetic on node values

XPath provides some functions (e.g.,


concat(), substring()) to facilitate the above.

This XML document can be


represented as a tree, as shown below

<?xml version="1.0"?>
<Document classification="secret">
<Para classification="unclassified">
One if by land, two if by sea;
</Para>
<Para classification="confidential">
And I on the opposite shore will be,
Ready to ride and spread the alarm
</Para>
<Para classification="unclassified">
Ready to ride and spread the alarm
Through every Middlesex, village and farm,
</Para>
</Document>

14

Document
/

PI
<?xml version=1.0?>

Element
Para

Text
One if

Element
Document

Attribute
classification=unclassified

Element
Para

Text
And I

Attribute
classification=confidential

Attribute
classification=secret

Element
Para

Text
Ready to

Attribute
classification=
unclassified

15

Execute XPath using


Oxygen XML

Type your XPath expression here


Change this to XPath 1.0

16

Use XPath Builder


for long XPath
expressions

17

Please Execute the


XPath Expressions
The following slides contain XPath
expressions.
It is important that you copy the expression
on the slide and paste it into Oxygen XML
to see what the expression does.
Now, drag and drop Document.xml (in the
example000 folder) into Oxygen XML.

18

Select all Para Elements

/Document/Para

19

/Document/Para
Hey XPath processor, position yourself at the Document node (i.e., /); use that as the
context node; from there select any child elements with the name Document (theres
only one); now use that as the context node and from there select any child elements
with the name Para (there are four, although only three are shown below due to space
limitations). Show the selected set of nodes.

Document
/

PI
<?xml version=1.0?>

Element
Para

Text
One if

Element
Document

Attribute
classification=unclassified

Element
Para

Text
And I

Attribute
classification=confidential

Attribute
classification=secret

Element
Para

Text
Ready to

Attribute
classification=
unclassified

20

Result
<Para classification="unclassified">
One if by land, two if by sea;
</Para>
<Para classification="confidential">
And I on the opposite shore will be,
Ready to ride and spread the alarm
</Para>
<Para classification="unclassified">
Ready to ride and spread the alarm
Through every Middlesex, village and farm,
</Para>
<Para classification="secret">
For the country folk to be up and to arm.
</Para>
Evaluating the XPath query results in selecting each Para
element, including its attribute and contents.

21

Heres how Oxygen


displays the results

Please understand what this is saying: the first Para element (Para[1]) and its
content is selected, the second Para element and its content is selected, the third
Para and its content is selected, and the fourth Para element and its content is
selected.

22

Absolute XPath Expression

/Document/Para
This is an absolute XPath expression. i.e., the
selection of nodes starts from the top of the
document (tree).

23

Not XML!
XPath syntax is not XML syntax!

24

Establish a Context Node

Click on this to establish Document


as the "context node"
(this will allow you to create XPath
expressions that are relative to it)

25

Relative XPath Expression

In Oxygen XML click on <Document> to


establish the context node and then type
this in the XPath box:
Para

26

Result
<Para classification="unclassified">
One if by land, two if by sea;
</Para>
<Para classification="confidential">
And I on the opposite shore will be,
Ready to ride and spread the alarm
</Para>
<Para classification="unclassified">
Ready to ride and spread the alarm
Through every Middlesex, village and farm,
</Para>
<Para classification="secret">
For the country folk to be up and to arm.
</Para>
Same result as before.

27

Select here

In Oxygen XML click on <Document> to


establish the context node and then type
this in the XPath box:

28

Result
<Document classification="secret">
<Para classification="unclassified">
One if by land, two if by sea;
</Para>
<Para classification="confidential">
And I on the opposite shore will be,
Ready to ride and spread the alarm
</Para>
<Para classification="unclassified">
Ready to ride and spread the alarm
Through every Middlesex, village and farm,
</Para>
<Para classification="secret">
For the country folk to be up and to arm.
</Para>
</Document>
The context node is selected, which is Document.
Thus the result is Document and its content.

29

Select all Para Descendents

//Para
The double slash means descendents.

30

Result
<Para classification="unclassified">
One if by land, two if by sea;
</Para>
<Para classification="confidential">
And I on the opposite shore will be,
Ready to ride and spread the alarm
</Para>
<Para classification="unclassified">
Ready to ride and spread the alarm
Through every Middlesex, village and farm,
</Para>
<Para classification="secret">
For the country folk to be up and to arm.
</Para>
All Para elements that descend from / are selected.

31

Select the first Para

//Para[1]

32

Result
<Para classification="unclassified">
One if by land, two if by sea;
</Para>

The first Para element is selected.

33

Select the last Para

//Para[last()]

34

Result
<Para classification="secret">
For the country folk to be up and to arm.
</Para>

last() is an XPath function. It returns a number


(in our example it returns 4). Thus the fourth
(last) Para element is selected.

35

Select the classification attribute


of the first Para
//Para[1]/@classification

36

Result

unclassified

The @ symbol means


attribute. Thus, the
value of the
classification attribute,
of the first Para
element, is selected.

37

Is the Document elements


classification top-secret?
/Document/@classification = 'top-secret'
The XPath expression
uses the equality
comparison operator.

38

Result
false

39

Comparison Operators
=
<
>
!=
<=
>=
Remember to escape the reserved characters:
Instead of < use &lt;
Instead of > use &gt;
Instead of <= use &lt;=
Instead of >= use &gt;=

40

Is the Document elements


classification top-secret or
secret?
(/Document/@classification = 'top-secret') or
(/Document/@classification='secret')
The XPath expression
uses the boolean or
operator.

41

Result
true

42

Boolean Operators
A or B
A and B
not(A)

43

Select all Paras with a secret


classification
//Para[@classification = 'secret']

44

Result
<Para classification="secret">
For the country folk to be up and to arm.
</Para>

45

Check that no Para has a


top-secret classification

not(//Para[@classification = 'top-secret'])

46

Result
true

47

Select the Paras that dont have a


top-secret classification

//Para[@classification != 'top-secret']

48

Result
<Para classification="unclassified">
One if by land, two if by sea;
</Para>
<Para classification="confidential">
And I on the opposite shore will be,
Ready to ride and spread the alarm
</Para>
<Para classification="unclassified">
Ready to ride and spread the alarm
Through every Middlesex, village and farm,
</Para>
<Para classification="secret">
For the country folk to be up and to arm.
</Para>
None of the Para elements have a top-secret classification.

Do Lab1

49

Establish a New Context Node

Make the second Para the context node

50

Select the Following Siblings

following-sibling::*

51

Result
<Para classification="unclassified">
Ready to ride and spread the alarm
Through every Middlesex, village and farm,
</Para>
<Para classification="secret">
For the country folk to be up and to arm.
</Para>
These Para elements are siblings (of the second Para element)
and they follow, i.e., they are following siblings.

52

Select the First


Following Sibling

following-sibling::*[1]

53

Result
<Para classification="unclassified">
Ready to ride and spread the alarm
Through every Middlesex, village and farm,
</Para>

54

Add Another Element

Add this <Test> element after the last Para

55

Set the Context Node

Make the second Para the context node

56

Select the Following


Para Siblings

following-sibling::Para

57

Result
<Para classification="unclassified">
Ready to ride and spread the alarm
Through every Middlesex, village and farm,
</Para>
<Para classification="secret">
For the country folk to be up and to arm.
</Para>
Although the Test element is a following sibling of Para[2], it is
not selected because the XPath expression selects only the Para
following siblings.

58

Select all Following Siblings

following-sibling::*

59

Result
<Para classification="unclassified">
Ready to ride and spread the alarm
Through every Middlesex, village and farm,
</Para>
<Para classification="secret">
For the country folk to be up and to arm.
</Para>
<Test>Hello World</Test>
The * symbol matches (selects) any element node.

60

Select the First Following


Para Sibling

following-sibling::Para[1]

61

Result
<Para classification="unclassified">
Ready to ride and spread the alarm
Through every Middlesex, village and farm,
</Para>

62

Select all Preceding Siblings

preceding-sibling::*

63

Result
<Para classification="unclassified">
One if by land, two if by sea;
</Para>
Para[2] has only one preceding sibling element node.

64

Establish a New Context Node

Click on Document to make it the


context node.

65

Equivalent!
Para[1]
child::Para[1]

The first XPath expression is called the abbreviated notation.


The second XPath expression is called the long notation.

66

Make Para[2] the context

Establish this as the context node.

67

Get parent element's classification

../@classification

Means go up one level (to the parent).

68

Equivalent!

../@classification
parent::*/@classification

69

Recall x, y Axes from School


The x, y axes enables us to navigate through space.
Similarly, we want to navigate through an XML
document. So we need some axes for navigating
through XML documents.
We need a much richer set of axes than the x, y
axes. We need axes that enables us to navigate to
child nodes, to all descendent nodes, to the parent
node, to all ancestor nodes, etc.

70

List of Axis

ancestor: use to select all ancestors


ancestor-or-self: use to select the current node plus all its ancestors
attribute: use to select attributes
child: use to select child nodes
descendant: use to select all the descendants
descendant-or-self: use to select the current node plus all its descendants
following: use to select everything in the document that follows the current
node
following-sibling: use to select the siblings that follow
namespace: use to select the namespaces that are in scope
parent: use to select the parent
preceding: use to select everything in the document that precedes the current
node
preceding-sibling: use to select the siblings that precede
self: use to select the current node

71

Load this XML Document


into Oxygen
<?xml version="1.0"?>
<FitnessCenter>
<Member level="platinum">
<Name>Jeff</Name>
<Phone type="home">555-1234</Phone>
<Phone type="work">555-4321</Phone>
<FavoriteColor>lightgrey</FavoriteColor>
</Member>
</FitnessCenter>

This is in the example000 folder, the file is FitnessCenter.xml

72
Document
/

PI
<?xml version=1.0?>

Element
FitnessCenter

ancestors

Element
Name

Element
Phone

preceding
sibling
Text
Jeff

Element
Member

Element
Phone

Element
FavoriteColor

Text
555-4321

Text
lightgrey

following
siblings
Text
555-1234

If the context node is the Member's first phone element then:


we can select all ancestors by:
all preceding siblings by:
ancestor::*
preceding-sibling::*
Which yields:
Which yields:
Member
Name
FitnessCenter

all following siblings by:


following-sibling::*
Which yields:
Phone
FavoriteColor

73
Document
/

PI
<?xml version=1.0?>

descendants

Element
FitnessCenter

Element
Member

Element
Name

Text
Jeff

Element
Phone

Element
Phone

Element
FavoriteColor

Text
555-1234

Text
555-4321

Text
lightgrey

If the context node is the FitnessCenter element then:


we can select all descendants by:
descendant::*
Which yields:
Member
Name
Phone, etc.

74

Using an Axis

axis::node
Either the name of an element or the * symbol

Examples: ancestor::*
child::Para

75

Reload this Document

Lets go back to this document.

76

Common Error
Distinguish between these two:
child::Para
child:Para
The first one has two colons, the second has only
one.
When specifying an axis you must follow it with
two colons. (Otherwise the XPath processor will
think that youre using a namespace!)

77

Default Axis
Para[1]
child::Para[1]
child is the default axis, i.e., if an XPath expression doesnt
specify an axis (see the first expression above) then, by default,
the child axis is used.
Do Lab2

78

XPath Functions
Thus far we have been creating XPath
expressions that select nodes and compare
nodes in the XML document.
The following slides show XPath
expressions that operate on nodes in the
XML document. This is accomplished using
XPath functions.

79

Count the number of


Para elements
count(//Para)

Result:
4

80

Count the number of Para


elements with secret
classification
count(//Para[@classification = 'secret'])

Result:
1

81

Add SCRIPT to the First Para

Add this word

82

Does the first Para element


contain the string SCRIPT?

contains(//Para[1], 'SCRIPT')

Result:
true

83

6 Kinds of Nodes
An XML document contains these kinds of
nodes:

Element nodes
Attribute nodes
Text nodes
Document node
Comment nodes
Processing instruction nodes

The node() function matches any kind of


node.

84

node() vs *
As weve seen, the * symbol matches
(selects) element nodes.
The node() function matches (selects) any
kind of node.

85

Select all nodes containing the


string SCRIPT

//node()[contains(., 'SCRIPT')]

For each node in the XML document:


If it contains SCRIPT then select (output) it.

86

This element node


contains SCRIPT
Document
/

PI
<?xml version=1.0?>

Element
Para

Text
One if
SCRIPT

This element node


contains SCRIPT

Attribute
classification=unclassified

Element
Para

Text
And I

This text node contains


SCRIPT

Element
Document

Attribute
classification=confidential

Attribute
classification=secret

Element
Para

Text
Ready to

Attribute
classification=
unclassified

87

Result
<Document classification="secret">
<Para classification="unclassified">
One if by land, two if by sea;SCRIPT
</Para>
<Para classification="confidential">
And I on the opposite shore will be,
Ready to ride and spread the alarm
</Para>
<Para classification="unclassified">
Ready to ride and spread the alarm
Through every Middlesex, village and farm,
</Para>
<Para classification="secret">
For the country folk to be up and to arm.
</Para>
</Document>
<Para classification="unclassified">
One if by land, two if by sea;SCRIPT
</Para>
One if by land, two if by sea;SCRIPT

88

Count the number of nodes


containing the string SCRIPT

count(//node()[contains(., 'SCRIPT')])

Result:
3

89

Select the first 20 characters of


the first Para
substring(//Para[1], 1, 20)

Result:
cr

One if by
10 spaces

carriage return

90

substring(string, num1, num2?)


The first two arguments of the substring
function are mandatory. The third argument
is optional.
If the third argument is omitted then the
function will return all the characters from
num1 to the end of the string.
substring(//Para[1], 10) returns all characters from character 10 onward

91

What's the length of the content of


the first Para?

string-length(//Para[1])

Result:
52

92

What's the name of the last child


element of Document?

name(/Document/*[last()])

Result:
Test

93

Convert Documents
classification to uppercase

translate(/Document/@classification, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')

Result:
SECRET

94

translate(string, from pattern,


to pattern)
The translate function has three arguments:
A value to be translated
A set of characters to convert from
A set of characters to convert to

Each character in string is examined. If that


character is in from pattern then it is changed to
the character at the same position in to pattern. If
that character is not in from pattern then it is
output unchanged.

95

Add a new <Cost> element

Add this element and establish


Document as the context node.

96

Multiply Cost by 2

Cost * 2

Result:
24

97

N mod X = the remainder of


dividing N by X

Cost mod 2

Result:
0

98

Arithmetic Operators

*
mod
- (must leave space on either side)
+
div

Do Lab3

99

Load this XML Document


into Oxygen
<?xml version="1.0"?>
<FitnessCenter>
<Member>
<Name>Jeff</Name>
<FavoriteColor>lightgrey</FavoriteColor>
</Member>
<Member>
<Name>David</Name>
<FavoriteColor>lightblue</FavoriteColor>
</Member>
<Member>
<Name>Roger</Name>
<FavoriteColor>lightyellow</FavoriteColor>
</Member>
<Employee>
<Name>Erika</Name>
</Employee>
<Employee>
<Name>Linda</Name>
</Employee>
<CEO>
<Name>Jack</Name>
</CEO>
<VP>
<Name>Dora</Name>
</VP>
</FitnessCenter>

See FitnessCenter_v2.xml in the example000 folder.

100

Establish FitnessCenter
as the Context Node

Click on this to make it the context node.

101

3 Forms of XPath Expressions


Path Expression: expression1/expression2
Example: Member/Name

Predicate Expression: expression1[expression2]


Example: Member[Name]

Union Expression: expression1|expression2


Example: Member/Name|Member/Age
Note: the "|" operator computes the union of its
operands, which must be node sequences.

102

Context Item
Consider this path expression: Member/Name, and this
predicate expression: Member[Name].
In these expressions Name is evaluated once for each item
in the sequence that results from evaluating Member.
<Member>
<Name>Jeff</Name>
<FavoriteColor>lightgrey</FavoriteColor>
</Member>
<Member>
<Name>David</Name>
<FavoriteColor>lightblue</FavoriteColor>
</Member>
<Member>
<Name>Roger</Name>
<FavoriteColor>lightyellow</FavoriteColor>
</Member>

103

Context Item
Evaluating the expression "Member" produces this
sequence of element nodes:
<Member>
<Name>Jeff</Name>
<FavoriteColor>lightgrey</FavoriteColor>
</Member>

<Member>
<Name>David</Name>
<FavoriteColor>lightblue</FavoriteColor>
</Member>

<Member>
<Name>Roger</Name>
<FavoriteColor>lightyellow</FavoriteColor>
</Member>

"Name" is evaluated once for each


item in this sequence. Each of these
Member nodes is the context item
for evaluating Name.
Defn: The context item is the item (node) that provides the context for evaluating an inner expression.

104

Meaning of "/"
Consider this path expression: Member/Name
The "/" means: "for each Member node, return the result of
evaluating Name".
<Member>
<Name>Jeff</Name>
<FavoriteColor>lightgrey</FavoriteColor>
</Member>
<Member>
<Name>David</Name>
<FavoriteColor>lightblue</FavoriteColor>
</Member>
<Member>
<Name>Roger</Name>
<FavoriteColor>lightyellow</FavoriteColor>
</Member>

Member/Name

<Name>Jeff</Name>
<Name>David</Name>
<Name>Roger</Name>

105

Meaning of "/" (concluded)


Here is the general form for using "/"
expression1/expression2

Each of these expressions must evaluate to


a node, or sequence of nodes.
Consequently, this is illegal:
Member/last()
This evaluates to an integer, not a node.

106

Meaning of []
Consider this predicate expression: Member[Name]
The predicate [Name] means: evaluate the expression "Name"
within the context node. If Name exists then return true, else false.
Thus, Member[Name] says: "give me all Member nodes that has a
Name child".

<Member>
<Name>Jeff</Name>
<FavoriteColor>lightgrey</FavoriteColor>
</Member>
<Member>
<Name>David</Name>
<FavoriteColor>lightblue</FavoriteColor>
</Member>
<Member>
<Name>Roger</Name>
<FavoriteColor>lightyellow</FavoriteColor>
</Member>

<Member>
<Name>Jeff</Name>
<FavoriteColor>lightgrey</FavoriteColor>
</Member>

Member[Name]

<Member>
<Name>David/Name>
<FavoriteColor>lighblue</FavoriteColor>
</Member>
<Member>
<Name>Roger</Name>
<FavoriteColor>lightyellow</FavoriteColor>
</Member>

Meaning of [] (concluded)
Here is the general form for using []
expression1[expression2]

This expression
must evaluate to
a boolean value
(true or false).
Consequently, all of these are legal:
Member[true()]
These will select all Member elements
Member[false()]
These will select no Member elements
Member[1 = 1]
Member[1 = 2]
This will select only the Member elements that
Member[Age]
This expression
must evaluate to
a node or node sequence.

have an Age child element.

107

108

Meaning of "|"
Consider this union expression: expression1|expression2
The union expression means, "create a sequence of nodes composed of the nodes
selected by expression1, unioned with the nodes selected by expression2.

<Member>
<Name>Jeff</Name>
<FavoriteColor>lightgrey</FavoriteColor>
</Member>
<Member>
<FavoriteColor>lightblue</FavoriteColor>
</Member>
<Member>
<Name>Roger</Name>
<FavoriteColor>lightyellow</FavoriteColor>
</Member>

Member[1]|Member[3]

<Member>
<Name>Jeff</Name>
<FavoriteColor>lightgrey</FavoriteColor>
</Member>
<Member>
<Name>Roger</Name>
<FavoriteColor>lightyellow</FavoriteColor>
</Member>

109

Context Position
Recall that an XPath expression returns a
sequence of items.
Consider one of those items in the
sequence. Its context position is the
position of the item in the sequence.

110

The context position is returned


by the function position()
Member[position() = 2]

Result:
<Member>
<Name>David/Name>
<FavoriteColor>lighblue</FavoriteColor>
</Member>

Evaluate the expression: Member


It yields a sequence of 3 Member nodes.
Give me the one at position 2.

111

Equivalent!
Member[position() = 2]
Member[2]

The latter is a shorthand for the former.

112

Context Size
Recall that an expression returns a sequence
of items.
The context size tells you the number of
items in the sequence.

113

The context size is returned by


the expression last()
Member[last()]

Result:
<Member>
<Name>Roger</Name>
<FavoriteColor>lightyellow</FavoriteColor>
</Member>

Evaluate the expression: Member


It yields a sequence of Member nodes.
Give me the last one.

114

Axis
There are many ways that you might want to navigate
through an XML tree. For example, from a context node
you might want to:

navigate to a child node


navigate to an ancestor node
navigate to a preceding sibling node
navigate to a descendant node, etc.

An axis is provided for each way that you might want to


navigate through an XML tree.
The syntax for using an axis is: axis::node

115

Categories of Axes
These are axes used for navigating forward in the XML
tree:

child
descendant
attribute
self
descendant-or-self
following-sibling
following

These are axes used for navigating backward in the XML


tree:

parent
preceding-sibling
preceding
ancestor
ancestor-or-self

116

Child Axis
The child axis is used to navigate to a child
node from the context node.
./child::Member[1]/child::Name

Starting from the context node, navigate to


a child node - the first Member. Now, using
that Member as the context node, navigate
to a child node - the Name node.

117
Document
/

PI
<?xml version=1.0?>

Element
FitnessCenter

child::Member[1]

Element
Member

Element
Member

context node (.)

Element
Member

child::Name
Element
Name

Text
Jeff

Element
FavoriteColor

Text
lightgrey

Element
Name

Text
David

Element
FavoriteColor

Text
lightblue

Element
Name

Text
Roger

Element
FavoriteColor

Text
lightyellow

118

The expression "*" means


any element node
./child::Member[1]/child::*

Starting from the context node, navigate to


a child node - the first Member. Now, using
that Member as the context node, navigate
to all child element nodes - the Name node
and the FavoriteColor node.

119

Don't forget to use two colons


Remember, it is child::Member
It is NOT child:Member
The XSLT processor will think that you mean a
Member element in a "child namespace"!

120

Descendant Axis
The descendant axis is used to navigate to a
node that is "under" the context node. The
node could be a child node, a grandchild, a
great-grandchild, etc.
./descendant::Name[1]

Starting from the context node, navigate to a descendant


node - the first Name descendant. (Note: descendants of a
node are considered in document order. Thus, this example
says to navigate, from the context node, to the first Name
element in the document.)

121

Load this XML Document


into Oxygen
<?xml version="1.0"?>
<FitnessCenter>
<Member level="platinum">
<Name>Jeff</Name>
<FavoriteColor>lightgrey</FavoriteColor>
</Member>
<Member level="gold">
<Name>David</Name>
<FavoriteColor>lightblue</FavoriteColor>
</Member>
<Member level="platinum">
<Name>Roger</Name>
<FavoriteColor>lightyellow</FavoriteColor>
</Member>
<Employee>
<Name>Erika</Name>
</Employee>
<Employee>
<Name>Linda</Name>
</Employee>
<CEO>
<Name>Jack</Name>
</CEO>
<VP>
<Name>Dora</Name>
</VP>
</FitnessCenter>

See FitnessCenter_v3.xml in the example000 folder.

122

Establish the Context Node

Make this the context node.

123

Attribute Axis
The attribute axis is used to navigate to an
attribute of the context node.
./child::Member[1]/attribute::level

Starting from the context node, navigate to


a child node - the first Member. Now, using
that Member as the context node, navigate
to an attribute node - the level attribute.
Note: if you want to select all attributes then
use: attribute::*

124

Self Axis
The self axis is used to select the current
node (i.e., here).
./child::*[not(self::Member)]/child::Name

Starting from the context node, navigate to


all child element nodes that are not Member
nodes. From each of the selected nodes,
navigate to a child node - Name.
This XPath expression will navigate to the
Name nodes containing: Erika, Linda, Jack,
Dora.

125

Incorrect
./child::*[not(Member)]/child::Name

This says: given the context node,


determine if there is not a Member node
within it.
This XPath expression will navigate to the
Name nodes containing: Jeff, David, Roger,
Erika, Linda, Jack, Dora.

126

Equivalent!
./*[not(Member)]/Name

./child::*[not(child::Member)]/child::Name

Both of these expressions say: starting at the context node go to all


child element nodes that do not have a Member child. Then, using
the elements selected, go to the child Name node.
The first uses the abbreviated XPath notation. The second uses the
expanded XPath notation. Here we see that the expanded notation
reduces ambiguity!
Do Lab4

127

Descendant-or-self Axis
This axis is used to navigate to the current
node and all its descendants.
descendant-or-self::*

Give the context node and all of


the element nodes that are under it.

128

Following-sibling Axis
This axis is used to navigate to a node that is "parallel" to the context
node (i.e., at the same hierarchy level) and follows the context node.
<Member>
<Name>Jeff</Name>
<FavoriteColor>lightgrey</FavoriteColor>
</Member>
<Member>
<Name>David</Name>
<FavoriteColor>lightblue</FavoriteColor>
</Member>
<Member>
<Name>Roger</Name>
<FavoriteColor>lightyellow</FavoriteColor>
</Member>
<Employee>
<Name>Erika</Name>
</Employee>
<Employee>
<Name>Linda</Name>
</Employee>
<CEO>
<Name>Jack</Name>
</CEO>
<VP>
<Name>Dora</Name>
</VP>

./child::Member[1]/following-sibling::Employee[2]

Starting from the context node, navigate to


a child node - the first Member. Now, using
that Member as the context node, navigate
to the second Employee sibling that follows the
Member node.

129
Document
/

PI
<?xml version=1.0?>

Element
FitnessCenter

Element
Member

Element
Member

Element
Member

context node (.)


Element
Name

Element
FavoriteColor

Element
Name

Element
FavoriteColor

Element
Name

Element
FavoriteColor

following-sibling
Text
Jeff

Text
lightgrey

Text
David

Text
lightblue

Text
Roger

Text
lightyellow

Note: a node is a following sibling of another node only if it has the same parent.
Consquently, the Name and FavoriteColor nodes in Member[2] and Member[3]
are not following-siblings of the Name in Member[1].

130

Following Axis
This axis is used to navigate to the nodes
that follow the context node.
./child::Member[1]/following::Name

Starting from the context node, navigate to


a child node - the first Member. Now, using
that Member as the context node, navigate
to all the Name nodes that follow.
This XPath expression will navigate to the
Name nodes containing: David, Roger.

131
Document
/

PI
<?xml version=1.0?>

child::Member[1]
Element
Member

Element
Member

Element
Name

Text
Jeff

Element
FitnessCenter

Element
FavoriteColor

Text
lightgrey

Element
Name

Text
David

context node (.)

Element
Member

Element
FavoriteColor

Text
lightblue

Element
Name

Text
Roger

Element
FavoriteColor

Text
lightyellow

following nodes

132
Document
/

PI
<?xml version=1.0?>

Element
A

Context node

Element
E

Element
D

Text

Element
C

Element
B

Element
F

Text

Element
H

Element
G

Text

Text

Element
I

Text

Element
J

Text

following nodes

133

<?xml version="1.0"?>
<A>
<B>
<D>...</D>
<E>
<F></F>
<G></G>
</E>
<H>...</H>
</B>
<C>
<I></I>
<J></J>
</C>
</A>

following::E

134

Parent Axis
This axis is used to navigate to the parent of
the context node.
Suppose that Member[1] is the context node
./parent::FitnessCenter
Starting from the context node, navigate to
the parent, provided it is <FitnessCenter>.
Suppose that we wanted to navigate to the
parent, whatever it is. We would use this: parent::*.
Note: if the context node is an attribute node, then its
parent is the element node that the attribute is attached to.

135

Preceding-sibling axis
This axis is used to navigate to a node that is "parallel" to
the context node (i.e., at the same hierarchy level) and
precedes the context node.
<Member>
<Name>Jeff</Name>
<FavoriteColor>lightgrey</FavoriteColor>
</Member>
<Member>
<Name>David</Name>
<FavoriteColor>lightblue</FavoriteColor>
</Member>
<Member>
<Name>Roger</Name>
<FavoriteColor>lightyellow</FavoriteColor>
</Member>
<Employee>
<Name>Erika</Name>
</Employee>
<Employee>
<Name>Linda</Name>
</Employee>
<CEO>
<Name>Jack</Name>
</CEO>
<VP>
<Name>Dora</Name>
</VP>

./child::*[last()]/preceding-sibling::Member[1]

Starting from the context node, navigate to


a child node - the last element node. Now, using
that node as the context node, navigate
to the first Member sibling that precedes it.

136

Preceding Axis
This axis is used to navigate to all the nodes
that come before the context node.
<Member level="platinum">
<Name>Jeff</Name>
<FavoriteColor>lightgrey</FavoriteColor>
</Member>
<Member level="gold">
<Name>David</Name>
<FavoriteColor>lightblue</FavoriteColor>
</Member>
<Member level="silver">
<Name>Roger</Name>
<FavoriteColor>lightyellow</FavoriteColor>
</Member>

./child::Member[last()]/preceding::Name

Starting from the context node, navigate to


a child node - the last Member. Now, using
that Member as the context node, navigate
to all the Name nodes that precede.
This XPath expression will navigate to the
Name nodes containing: David, Jeff.

137

Load this XML document


into Oxygen

Make this the context node

<?xml version="1.0"?>
<Book>
<Title>Origin of Wealth</Title>
<Chapter>
<Title>The Paradigm Shift</Title>
<Section>
<Title>The Question</Title>
<Para>I sat perched on </Para>
</Section>
</Chapter>
</Book>
This is Book.xml in the example000 folder

138

Ancestor Axis
This axis is used to navigate to an ancestor
node.
ancestor::*[2]/child::Title

Navigate to the grandparent


and from there navigate to the
child Title node.
Result:
<Title>The Paradigm Shift</Title>

139

Ancestor-or-self Axis
This axis is used to navigate to the current
node and its ancestors.
ancestor-or-self::*

Select the current node and all its ancestors

text() is a function that selects


text nodes
<Member>
<Name>Jeff</Name>
<FavoriteColor>lightgrey</FavoriteColor>
</Member>

Element
Member

Note: cr = carriage return

Text
"cr
"

Element
Name

Text
Jeff

Text
"cr
"

Element
FavoriteColor

Text
"cr"

Text
lightgrey

Suppose that the context node is the Member element. Then this expression: text()
will result in selecting the 3 child text nodes.

140

141
Document
/

PI
<?xml version=1.0?>

Element
FitnessCenter

Element
Member

Element
Member

Element
Name

Text
Jeff

Element
FavoriteColor

Text
lightgrey

Element
Name

Text
David

/FitnessCenter/Member[1]/Name selects

Element
Member

Element
FavoriteColor

Text
lightblue

Element
Name

Text
Roger

Element
FavoriteColor

Text
lightyellow

142
Document
/

PI
<?xml version=1.0?>

Element
FitnessCenter

Element
Member

Element
Member

Element
Name

Text
Jeff

Element
FavoriteColor

Text
lightgrey

Element
Name

Text
David

/FitnessCenter/Member[1]/Name/text() selects

Element
Member

Element
FavoriteColor

Text
lightblue

Element
Name

Text
Roger

Element
FavoriteColor

Text
lightyellow

143

node() is a function that selects


text, element, document, comment and PI nodes
<Member>
<Name>Jeff</Name>
<!-- This is a comment -->
<?bar foo="blah"?>
</Member>

Element
Member

Text
"cr
"

Element
Name

Text
"cr
"

Comment
This is a comment

Text
"cr
"

PI
foo="blah"

Text
Jeff

Suppose that the context node is the Member element. Then this expression: node() will result
in selecting the 4 child text nodes, the 1 element node, the 1 comment node, and the 1 PI node.

Text
"cr"

144

Examples
child::para selects the para element children of the context node.
child::* selects all the element children of the context node.
child::text() selects all text node children of the context node.
child::node() selects all the children of the context node, whatever their node type (i.e., text node, element
node, document (/) node, comment node, or processing instruction node)
attribute::name selects the name attribute of the context node.
attribute::* selects all the attributes of the context node.
parent::node() selects the parent of the context node. If the context node is an attribute node, this expression
returns the element node to which the attribute is attached.
descendant::para selects all the para element descendants of the context node.
ancestor::div selects all div ancestors of the context node.
ancestor-or-self::div selects the div ancestors of the context node and, if the context node is a div element, the
context node as well.
descendant-or-self::para selects the para element descendants of the context node and, if the context node
is a para element, the context node as well.
self::para selects the context node if it is a para element, and otherwise nothing.

145

Expanded Notation
The expanded notation has several advantages:
Nonambiguous: it makes it very clear how you are
navigating through the XML tree.
Powerful: it provides the means to navigate the XML
tree in pretty much every way that you might desire.

But it has a disadvantage:


Verbose: your XPath expressions can get pretty long,
even for simple things.

146

Abbreviated Notation
We will now look at the abbreviated notation.
Here are its advantages:
Brevity: the XPath expressions are much shorter.

Here are its disadvantages:


Ambiguous: sometimes the expression can be misinterpreted,
such as we saw with this expression: ./*[not(Member)]/Name
Less powerful: there are some things that you simply can't
do with the abbreviated notation, e.g., navigate to ancestors,
navigate to preceding siblings, navigate to following siblings.

147

Omitting the Axis


Recall that when using the expanded notation you
provide 3 things:
An axis (e.g., child, ancestor, descendant)
A pair of colons (i.e., ::)
A node name (or "*" if you wish to navigate to all element
or attribute nodes)

That is, here is the general form: axis::node


The abbreviated notation allows you to omit the axis
and colons. What is the default axis?

148

Default Axis
The default axis is child. Thus, these forms
are equivalent:
./child::*[not(Member)]/child::Name

./child::*[not(child::Member)]/child::Name

No axis is specified. Consequently, an XPath processor


will use the default axis: child. Thus, it will treat this as:
child::Member
Member[Name]

is equivalent to:

child::Member[child::Name]

149

Examples of using the Abbreviated


Notation and the Default Axis
./child::Member[1]/child::Name
expanded notation

./child::*[not(child::Member)]/child::Name
expanded notation

./Member[1]/Name
abbreviated notation

./*[not(Member)]/Name
abbreviated notation

150

@ is the abbreviated notation for


the attribute axis
./child::Member[1]/attribute::level
expanded notation

./Member[1]/@level
abbreviated notation

Do Lab5

151

Load this XML Document


into Oxygen
Make this the context node

<?xml version="1.0"?>
<Book>
<para>paragraph #1</para>
<para>paragraph #2</para>
<para>paragraph #3</para>
<Chapter>
<para>paragraph #4</para>
<para>paragraph #5</para>
<Section>
<para>paragraph #6</para>
</Section>
</Chapter>
</Book>
This is Book_v2.xml in the example000 folder

152

// is the abbreviated notation for


descendant-or-self::node()/
.//para
abbreviated notation

./descendant-or-self::node()/child::para
expanded notation

These expressions both say: starting from the context node select all
the descendant nodes as well as the context node. Now, for each of
them select the child para elements. In other words, this results in
selecting all para elements that descend from the context node.

153

What will be the result?


<?xml version="1.0"?>
<Book>
<para>paragraph #1</para>
<para>paragraph #2</para>
<para>paragraph #3</para>
<Chapter>
<para>paragraph #4</para>
<para>paragraph #5</para>
<Section>
<para>paragraph #6</para>
</Section>
</Chapter>
</Book>

./descendant-or-self::node()/child::para

Result:
<para>paragraph #1</para>
<para>paragraph #2</para>
<para>paragraph #3</para>
<para>paragraph #4</para>
<para>paragraph #5</para>
<para>paragraph #6</para>

154

What will be the result?


<?xml version="1.0"?>
<Book>
<para>paragraph #1</para>
<para>paragraph #2</para>
<para>paragraph #3</para>
<Chapter>
<para>paragraph #4</para>
<para>paragraph #5</para>
<Section>
<para>paragraph #6</para>
</Section>
</Chapter>
</Book>

.//para[1]

Result:
<para>paragraph #1</para>
<para>paragraph #4</para>
<para>paragraph #6</para>

155

Let's see why


.//para[1]

is equivalent to:

descendant-or-self::node()/child::para[1]

Select all nodes that descend from the context node,


including the context node. For each of them, select
the first para child element.

156

Contrast with this!


<?xml version="1.0"?>
<Book>
<para>paragraph #1</para>
<para>paragraph #2</para>
<para>paragraph #3</para>
<Chapter>
<para>paragraph #4</para>
<para>paragraph #5</para>
<Section>
<para>paragraph #6</para>
</Section>
</Chapter>
</Book>

./descendant::para[1]

Result:
<para>paragraph #1</para>

157

Let's see why


./descendant::para[1]

Select all para elements that descend from the


context node. Then select the first one.

158

Lesson Learned
.//para[1]

./descendant::para[1]

Not equivalent!

Do Lab6

159

.. is an abbreviation of
parent::node()
..
abbreviated notation

../para
abbreviated notation

parent::node()
expanded notation

parent::node()/child::para
expanded notation

160

. is an abbreviation of self::node()
.
abbreviated notation

self::node()
expanded notation

161

Good Example
<Member level="platinum">
<Name>Jeff</Name>
<FavoriteColor>lightgrey</FavoriteColor>
</Member>
<Member level="gold">
<Name>David</Name>
<FavoriteColor>lightblue</FavoriteColor>
</Member>
<Member level="platinum">
<Name>Roger</Name>
<FavoriteColor>lightyellow</FavoriteColor>
</Member>

Member[FavoriteColor='lightblue']
<Member level="gold">
<Name>David</Name>
<FavoriteColor>lightblue</FavoriteColor>
</Member>

162

Let's see its Expanded Notation


Member[FavoriteColor='lightblue']

child::Member[child::FavoriteColor='lightblue']

Select all Member child elements which have a FavoriteColor


child element whose value is lightblue.

163

Examples
para selects the para element children of the context node.
* selects all element children of the context node.
text() selects all text node children of the context node.
@name selects the name attribute of the context node.
@* selects all the attributes of the context node.
para[1] selects the first para child of the context node.
para[last()] selects the last para child of the context node.
*/para selects all para grandchildren of the context node.
/book/chapter[5]/section[2] selects the second section of the fifth chapter of the book whose parent is the document node.
chapter//para selects the para element descendants of all the chapter element children of the context node.
//para selects all the para element descendants in the document
//@version selects all the version attribute nodes in the document
//list/member selects all the child member elements of all the list elements.
.//para selects all para element descendants of the context node.
.. selects the parent of the context node.
../@lang selects the lang attribute of the parent of the context node.
para[@type='warning'] selects all para children of the context node that have a type attribute with value warning.
chapter[title='Introduction'] selects the chapter children of the context node that have one or more title children
whose value equals Introduction.
chapter[title] selects the chapter children of the context node that have one or more title children.
employee[@secretary and @assistant] selects all the employee children of the context node that have both a secretary
attribute and an assistant attribute.
Member[Name='Jeff' or Name='Roger']/FavoriteColor selects all FavoriteColor children of Member elements that
have a Name child element equal to Jeff or Roger.

164

Summary
Expanded Notation
Abbreviated Notation
child::para
para
descendant::para
attribute::level
@level
self::node()
.
descendant-or-self::node()/child::para .//para
following-sibling::para
following::name
parent::node()
..
preceding-sibling::Member
preceding::Name
ancestor::FitnessCenter
ancestor-or-self::Title

165

Predicates
A predicate consists of an expression, called a
predicate expression, enclosed in square
brackets.
A predicate serves to filter a sequence-retaining some items and discarding others.
Those items for which the predicate evaluates
to true are retained, and those for which the
predicate evaluates to false are discarded.

166

Predicates
path-expression[predicate-expression]
The predicate-expression
is evaluated within the context
provided by the path-expression.
The result of evaluating the
predicate expression is a boolean value:
true or false.

167

Numeric Predicates
If the predicate expression is a number, then the predicate
evaluates to true if the number equals the context position.
Consider this XPath: Member[2]
The path expression yields this sequence:

<Member>
<Name>Jeff</Name>
<FavoriteColor>lightgrey</FavoriteColor>
</Member>

<Member>
<Name>David</Name>
<FavoriteColor>lightblue</FavoriteColor>
</Member>

<Member>
<Name>Roger</Name>
<FavoriteColor>lightyellow</FavoriteColor>
</Member>

The predicate is evaluated against each of these items. Since the predicate is a number it will be
compared against each item's context position. For the first item its context position is 1 and 1 = 2
so the first item is discarded. For the second item its context position is 2 and 2 = 2 so the second item
is retained. For the third item its context position is 3 and 3 = 2 so the third item is discarded.

168

Element Predicates
If the predicate expression is an element node, then the predicate evaluates to
true if the node exists. (Conversely, a predicate expression which evaluates to
an empty sequence evaluates to false)
Consider this predicate expression: Member[FavoriteColor]
Suppose the Member path expression yields this sequence:

<Member>
<Name>Jeff</Name>
<FavoriteColor>lightgrey</FavoriteColor>
</Member>

<Member>
<Name>David</Name>
</Member>

<Member>
<Name>Roger</Name>
<FavoriteColor>lightyellow</FavoriteColor>
</Member>

Note that the second Member does not have a FavoriteColor. The predicate is evaluated against
each of these items. Since the predicate is an element node the XSLT processor will determine if
the node exists for each item. For the first Member there does exist a FavoriteColor child element so
it is retained. For the second Member there does not exist a FavoriteColor child element so it is
discarded. For the third Member there does exist a FavoriteColor child element so it is retained.

169

Boolean Predicates
If the predicate expression is a boolean expression,
then the predicate evaluates to true if the boolean
expression evaluates to true.
Consider this XPath: Member[Name = 'Jeff']
Suppose the Member path expression yields this
sequence:
<Member>
<Name>Jeff</Name>
<FavoriteColor>lightgrey</FavoriteColor>
</Member>

<Member>
<Name>David</Name>
<FavoriteColor>lightblue</FavoriteColor>
</Member>

<Member>
<Name>Roger</Name>
<FavoriteColor>lightyellow</FavoriteColor>
</Member>

The predicate is evaluated against each of these items. The first Member has a child Name element
with a value equal to Jeff, so it is retained. The second and third Member elements have a child Name
element, but with a value other than Jeff, so they are discarded.

170

Multiple Predicates
It is legal to have multiple predicates:
path-expression[predicate-expression1] [predicate-expression2]

They are evaluated as follows:


{sequence of nodes selected by path-expression}
filter using predicate-expression1
{sequence of nodes after filtering with predicate-expression1}
filter using predicate-expression2
{sequence of nodes after filtering with predicate-expression2}

171

Order Matters!
<?xml version="1.0"?>
<FitnessCenter>
<Member level="platinum">
<Name>Jeff</Name>
<FavoriteColor>lightgrey</FavoriteColor>
</Member>
<Member level="gold">
<Name>David</Name>
<FavoriteColor>lightblue</FavoriteColor>
</Member>
<Member level="platinum">
<Name>Roger</Name>
<FavoriteColor>lightyellow</FavoriteColor>
</Member>
</FitnessCenter>

Member[@level='platinum'][2]

<Member level="platinum">
<Name>Roger</Name>
<FavoriteColor>lightyellow</FavoriteColor>
</Member>

Member[2] [@level='platinum']

-- empty --

Do Lab7

172

Arithmetic Expressions
XPath provides these arithmetic operators:
+ (addition)
- (subtraction and unary negation)
* (multiplication)
div (division)
mod (modulus, i.e., the remainder from division)
Example: child::Cost * 2 (multiply the value of the Cost child
element by 2)
Example: position() mod 2 = 0 (this expression will evaluate to
true for context items at even positions, and false otherwise)

173

Boolean Operators
XPath provides these boolean operators:
and
or
not
Example: child::Cost and child::Member (This expression will
evaluate to true only if there exists a Cost child element
and a Member child element)
Example: ((child::Cost * 2 = 50) and (child::Member))

174

Parenthesized Expressions
Use parentheses to ensure that your
expressions are evaluated in the order you
desire.
Example: (child::Cost and child::Member) or (child::Cost and child::Test)
This expression will evaluate to true if there exists a Cost child
element and a Member child element, or there exists a Cost child
element and a Test child element.

175

Comparison Operators
These general comparison operators are
available:
= | != | < | <= | > | >=

176

Load this XML Document


into Oxygen
Make this the context node

<?xml version="1.0"?>
<FitnessCenter>
<Member>
<Name>Jeff</Name>
<Age>39</Age>
</Member>
<Member>
<Name>David</Name>
<Age>33</Age>
</Member>
<Member>
<Name>Roger</Name>
<Age>36</Age>
</Member>
</FitnessCenter>
This is FitnessCenter_v4.xml in the example000 folder.

177

General Comparison
Note that I am not specifying a specific Member.
Consequently, I am comparing all Member Ages.
<?xml version="1.0"?>
<FitnessCenter>
<Member>
<Name>Jeff</Name>
<Age>39</Age>
</Member>
<Member>
<Name>David</Name>
<Age>33</Age>
</Member>
<Member>
<Name>Roger</Name>
<Age>36</Age>
</Member>
</FitnessCenter>

Member/Age = 39
Member/Age != 20
Member/Age < 40
Member/Age <= 40
Member/Age > 30
Member/Age >= 30

Result:
Member/Age = 39 true
Member/Age != 20 true
Member/Age < 40 true
Member/Age <= 40 true
Member/Age > 30 true
Member/Age >= 30 true

178

General Comparison
<?xml version="1.0"?>
<FitnessCenter>
<Member id="1" level="platinum">
<Name>Jeff</Name>
<Phone type="home">555-1234</Phone>
<Phone type="work">555-4321</Phone>
<FavoriteColor>lightgrey</FavoriteColor>
<MembershipFee>340</MembershipFee>
<Age>39</Age>
</Member>
<Member id="2" level="gold">
<Name>David</Name>
<Phone type="home">383-1234</Phone>
<Phone type="work">383-4321</Phone>
<FavoriteColor>lightblue</FavoriteColor>
<MembershipFee>500</MembershipFee>
<Age>33</Age>
</Member>
<Member id="3" level="platinum">
<Name>Roger</Name>
<Phone type="home">888-1234</Phone>
<Phone type="work">888-4321</Phone>
<FavoriteColor>lightyellow</FavoriteColor>
<MembershipFee>340</MembershipFee>
<Age>36</Age>
</Member>
</FitnessCenter>

Member/Age = 39?
39

Does there exist an Age value


that equals 39? Yes!

Member/Age = 39 is equivalent to: (Member[1]/Age = 39) or (Member[2]/Age = 39) or (Member[3]/Age = 39)

179

Use General Comparison to


Compare Two Sequences
<?xml version="1.0"?>
<FitnessCenter>
<Member>
<Name>Jeff</Name>
<Age>39</Age>
<Salary units="thousands">20</Salary>
</Member>
<Member>
<Name>David</Name>
<Age>33</Age>
<Salary units="thousands">39</Salary>
</Member>
<Member>
<Age>36</Age>
<Salary units="thousands">45</Salary>
</Member>
</FitnessCenter>

Member/Age = Member/Salary

Result:
Member/Age = Member/Salary true

"Is there is an Age value


which equals a Salary value."

180

All Combinations of
Sequence Values are Compared
Age
39
33
36

Salary
20
39
45

181

XPath Functions
XPath provides a lot of functions for you to use. We have
already seen some, such as position(), last(), text(), node(),
count(), and translate().
Here's how the XPath functions are categorized:
String functions: those functions which when evaluated return a string.
Boolean functions: those functions which when evaluated return a
boolean value (true or false).
Number functions: those functions which when evaluated return a
number.
Node functions: those functions which when evaluated return a node.
Namespace functions: those functions that are intended for use with
namespaces.

182

Notation
Some functions have optional arguments. For
example, the name function has an optional
argument. I will use "?" after the argument to
indicate that it is optional, e.g., name(node?).
Some functions allow zero or more occurrences of
an argument. For example, the concat function
allows zero or more strings after the first two
arguments. I will use "*" after the argument to
indicate zero or more occurrences, e.g.,
concat(string, string, string*)

183

String Functions
name(node?) - this function returns the name of a node. If
no argument is provided then it returns the name of the
context item.
string(object?) - If object is a node this function returns the
value of the node (if the node is not a leaf node then it
concatenates the values of all the leaf nodes that are under
it)
concat(string, string, string*) - this function concatenates
all its arguments. There must be at least two arguments.
Example: concat(Name; , child::Name)

184

String Functions (cont.)


substring-before(string1, string2) - this function returns a
string representing the substring of string1 that precedes
the first occurrence of string2, or the empty string if
string1 does not contain string2.
substring-after(string1, string2) - this function returns a
string representing the substring of string1 that follows the
first occurrence of string2, or the empty string if string1
does not contain string2.
Example: substring-before(child::Phone, '555')
Example: substring-after(child::Phone, '555')

185

String Functions (cont.)


substring(string, number1, number2?) - this function returns a
string representing the substring of string starting at the
position specified by number1 with the length specified by
number2. If number2 is not specified then it returns the
substring starting at the position specified by number1, and
continuing to the end of string.
translate(string1, string2, string3) - this function returns a
string obtained by converting each character in string1 that is
contained in string2 into the character in string3 that is at the
same position as in string2. For those characters in string1
which are not present in string2, they are returned untouched.

186

substring(string, num1, num2?)


Example: substring('1234567890', 2, 5) returns '23456'

187

String Functions (concluded)


normalize-space(string?) - this function returns a string
obtained by trimming leading and trailing whitespaces
(space, carriage return, tab, linefeed) off the argument, and
replacing sequences of whitespaces by a single space. If
the argument is omitted, it defaults to the context node
converted to a string. In other words, these two function
calls are equivalent:
normalize-space()
is equivalent to:
normalize-space(string(self::*))

188

Boolean Functions
starts-with(string1, string2) - this function returns true if
string1 starts with string2, and otherwise returns false.
contains(string1, string2) - this function returns true if
string1 contains string2, and otherwise returns false.
Example: starts-with(child::Phone, '555')
Example: contains(child::FavoriteColor, 'blue')

189

Boolean Functions (concluded)


boolean(object) - this function converts object to a boolean value as
follows:
if object is a number (not zero) then the function returns true, if object is zero
then the function returns false.
if object is a node which exists then the function returns true; if the node does not
exist then the function returns false.
if object is a string of length greater than zero then the function returns true;
otherwise the function returns false.

true() - this function returns true


false() - this function returns false
lang(string) - this function returns true if the xml:lang value of the
context item matches string, and false otherwise. (Recall the default
value of xml:lang is 'EN')

190

Number Functions
position() - this function returns an integer, representing the position of the
context item within a sequence of items.
last() - this function returns an integer, representing the context size.
count(node sequence) - this function returns an integer representing the
number of nodes in node sequence.
string-length(string?) - this function returns an integer representing the
number of characters in string. If the argument is omitted, it defaults to the
context node converted to a string.

Example: string-length(child::FavoriteColor)

191

Number Functions (concluded)


number(object?) - this function converts object to a number as
follows:
if object is a number then it returns the number.
if object is a boolean true then it returns 1, if object is a boolean false then it
returns 0.
if object is a node then it returns the value of the node.

sum(node sequence) - this functions sums up the values of all the


nodes that are identified by node sequence.
floor(number) truncates the number.
ceiling(number) next integer.
round(number) - rounds the number, e.g., 12.5 rounds to 13, -12.5
rounds to -12.

192

floor(), ceiling(), round()


Example: floor(2.5) returns 2
Example: ceiling(2.5) returns 3

Example: round(2.3) returns 2

193

Node Functions
text() - this function matches on any text node.
node() - this function matches on any text, element,
document, comment, or PI node.
id(node id) - this function returns the node with an ID
value equal to node id.
Example: id(child::GuestAuthor/BookForSigning/@isbn-ref)
will return the element which has an ID value that
matches isbn-ref.

194

Open this file in Oxygen

Establish this
as the context
node

<?xml version="1.0"?>
<FitnessCenter xmlns="http://www.gym.com">
<Member level="platinum">
<Name>Jeff</Name>
<Phone type="home">555-1234</Phone>
<Phone type="work">555-4321</Phone>
<FavoriteColor>lightgrey</FavoriteColor>
</Member>
</FitnessCenter>
This is FitnessCenter_v5.xml in the example000 folder.

195

Namespace Terminology
{http://www.gym.com}Member

Local name
Namespace URI
Expanded name = The combination of the namespace URI and the local name

196

Namespace Terminology (cont.)


<gym:FitnessCenter xmlns:gym="http://www.gym.com">
<gym:Member>

</gym:FitnessCenter>

<gym:Member>

prefix

197

local-name(node?)
This is an XPath function which returns a
string, corresponding to the local name of
the node.
local-name(.)
Result:
Name

198

namespace-uri(node?)
This is an XPath function which returns a string
corresponding to the namespace URI of the node.

namespace-uri(.)

Result:
http://www.gym.com

199

Congratulations!
You now know everything there is to know
about XPath 1.0!
We have covered the entire XPath
specification. We have left no stone
unturned.

Das könnte Ihnen auch gefallen