Xpath, Xpointer, and Xlink: in This Chapter
Xpath, Xpointer, and Xlink: in This Chapter
3
IN THIS CHAPTER
• Meet a Few of XML’s Relatives 52
• XLink—Resource Relationship
Management 76
Although syntactically different, XPath provides the same access to XML document data as
T-SQL does to SQL Server data. The XPath language is used by XSLT (covered in Chapter 7,
“Transforming XML with XSLT and ASP.NET”) and XPointer to access data found within
specific XML document elements, attributes, and so on. 3
XPOINTER, AND
So what does XPath syntax look like? You may be surprised to learn that its syntax does not
resemble XML’s syntax at all. In some ways it resembles a syntax that you are more than
XPATH,
XLINK
likely used to working with: the Windows file system.
The Windows file system emulates a hierarchical structure with the drive letter representing the
root of all other files and folders on that drive. An XML document is structured hierarchically
with the root element (also called the root node) containing different child elements (or
nodes). These child elements may themselves contain other child elements.
To access a folder on one of your drives ( C: for example), your computer follows a path simi-
lar to the following:
c:\temp\subFolder1\subFolder2\xmlFile.xml
TIP
As a point of review, you cannot simply add C: as the root element name. Remember
in Chapter 2 that we discussed the concept of qualified namespaces. Putting the
colon in the root name makes the parser think that C was declared as a qualified
namespace somewhere in the document. Because it can’t find the declaration (or the
element name after the colon), the parser will raise an error.
If you wanted to access subFolder2 in the preceding XML document using XPath syntax, you
would simply type the following:
C/temp/subFolder1/subFolder2
You could also type a shorthand version. This version of the query searches for all subFolder2
nodes located anywhere within the XML document:
//subFolder2
You’re now an XPath expert! Well, the word “expert” may be a little strong at this point, but
your experience in working with the Windows file system should help you in understanding
how XPath works. XPath is, of course, much more powerful than this simple example. Aside
from its basic syntax, the XPath language also includes its own set of functions to provide
additional utilities such as formatting strings and numbers or performing mathematical
calculations.
Before going into more detail about XPath, it’s important that you realize that it is not
designed as a standalone language. Going back to the Windows file system comparison, with-
out having access to a DOS command prompt, File Manager, or Windows Explorer, typing the
path to a file wouldn’t get you very far and you definitely wouldn’t find the file or folder you
were looking for. The syntax you saw earlier to access a file is functional only when used in
conjunction with another language or program (such as a command prompt). XPath was
designed in the same manner. It is useful only when used with another language such as
XPointer or XSLT.
XPath Basics
The XPath specification defines a term named ”Location Steps” that sums up how the XPath
language actually works. To get to a particular node’s location, you have to list the steps to get
there using an XPath expression or pattern. Going back to the first XPath sample, we defined
the starting point as C and listed each step that should be followed to walk through the element
nodes to get to the destination data. Each step of the process was separated by a / character.
04 0672320398 CH03 7/24/01 10:45 AM Page 55
Let’s clarify this a little more through giving a simple real-life example. Getting to a node
within a document is very similar to explaining your family lineage. If a friend asked you
about a portion of your family line going back to your great grandfather, you may give the
following information using XPath syntax:
Great_Grandfather/Grandmother/Mother/Self
You can see from this sample that each step in your family lineage is separated by the /
character.
Another important term used in the XPath specification is that of the context node. The context
node is the node being evaluated at each step of an XPath expression. In your family lineage
example, the context node is first your Great_Grandfather. The context changes to the
Grandmother node and then moves to the Mother node. Finally, the context node is Self. This
same logic applies to nodes being evaluated at each step of an XPath expression.
The context node becomes important as evaluations are being done on it. If someone asks you
how many children your ______ had, it would be difficult to answer the question unless the
blank was filled in (unless you can read minds of course). You need to know where to start (the
context) in order to reply. If, however, someone asks you how many children your great grand- 3
father had, you can now provide an answer because you have a context from which to start.
XPOINTER, AND
The path to a particular node within an XML document is constructed from three pieces of
XPATH,
XLINK
information:
• An Axis Type
• A Node Test
• Predicates (filtering)
The following sections explain each of these items in turn. After that discussion, we’ll discuss
XPath functions and get into some examples so that you can see more XPath expressions at
work.
Axis Types
The family lineage XPath statement we looked at earlier took advantage of some XPath abbre-
viations to make things look a little nicer. Without using abbreviations, the same statement
would look like this:
Great_Grandfather/child::Grandmother/child::Mother/child::Self
Don’t worry about the :: characters. We’re not going to define any C++ interfaces or anything
like that. The child:: syntax is one type of axis defined by the W3C that can be used when
you’re trying to locate a node within a document. Each axis is followed by two colons (::)
when used within an XPath expression. Axes are somewhat intimidating at first glance but are
04 0672320398 CH03 7/24/01 10:45 AM Page 56
very useful when you know a few basics about how they work. Table 3.1 contains all the avail-
able axes as defined in the XPath specification.
Although many of the axes, such as self, child, and parent are self-explanatory, a few are
not as obvious at first. Let’s take a look at a few axes examples based on Listing 3.1.
Assuming that the context node is <father>, the descendant axis to this node would, as the
axis description says, select all descendants, which in this case would be the <self>,
<sister>, <brother>, and <child> nodes. Which nodes would be included in the descendant-
or-self axis if the <father> node is still the context node? This axis would contain the
<father>, <self>, <sister>, <brother>, and <child> nodes. Keep in mind that although this
example uses the element named self, this has nothing to do with the word self as contained
in the descendant-or-self axis. self as used in the axis name simply refers to the context
node, which is <father> in this example. 3
XPOINTER, AND
The following are a few more examples that simply list the axis name and nodes contained
within it. Assume that the <self> node is now the context node:
XPATH,
XLINK
Axis Included Nodes
following-sibling <sister>, <brother>
preceding-sibling none
ancestor <father>, <grandMother>, <greatGrandfather>,
<familyLine>
preceding none
Node Tests
Node tests let you specify what type of node to locate relative to the context node. Each of the
previously discussed axes have their own principal node type. For those axes that can contain
04 0672320398 CH03 7/24/01 10:45 AM Page 58
elements, the principle node type is element. Because the attribute axes can contain only attrib-
utes, its principle node type is. . . you guessed it, attribute.
The previous examples have performed node tests to check for element nodes only. However,
you could have done other types of node tests if you had wanted to get to a different location
in the document other than an element. The other node tests you could have used include
• The * wildcard character, which includes all items in the current axis. The wildcard
works in a manner similar to the SQL * wildcard character used in SELECT statements.
• text(), which includes all text nodes in the current axis.
• node(), which includes all nodes in the current axis.
• comment(), which includes all comments in the current axis.
• processing-instruction(), which includes all processing-instructions in the current axis.
Although you’ll have the opportunity to see plenty of examples of node tests in action, the fol-
lowing are a few simple examples with explanations to get you started:
Predicates
Using axes and node tests can help in reaching a specific location within an XML document.
But what if the context node contains four children that are elements and you want to select
only the third child element? You can use the child axis and element node test to get to the four
children, but neither the axes nor node tests help you to select the third element only.
Predicates, otherwise known as WHERE clauses, help solve this dilemma for you. A predicate
helps to filter out unwanted nodes by taking advantage of built-in functions. This process
is very similar to using the RowFilter property of the ADO.NET DataView class. Using
ADO.NET, filtering out records that don’t have a specific ID (as defined in intID below) is
as easy as typing the following code:
dataView.RowFilter = “ID = “ + intID;
Using XPath, filtering out nodes that don’t meet specific requirements is as easy as typing
child::sibling[position()=3]
This XPath statement uses a predicate to select the third sibling child of the context node.
04 0672320398 CH03 7/24/01 10:45 AM Page 59
You can see that a predicate is started and ended by using the [ and ] character tokens.
XPath has several built-in functions, which you’ll learn more about in a moment, that can be
used within the predicate statement. The preceding example used the position() function.
Using one or more of these functions in combination with comparative operators, the processor
performs the necessary checks on the current node-set to see which nodes should remain and
should be excluded. If you’re wondering what a node-set is, think of it as another form of an
ADO.NET DataSet. The difference is that the node-set contains a collection of XML nodes,
whereas the DataSet contains records returned from a data source.
The predicate statement as a whole produces a Boolean value after it is evaluated. Either the
predicate statement is true and the node being evaluated is included in the node-set, or it is
false and the node is excluded from the node-set. This Boolean value is derived by comparing
the result of a function call to a value using comparative operators, including
• =, !=
• -, +, *
• and, or
3
• div, mod
XPOINTER, AND
• | (union operator)
XPATH,
XLINK
Your first look at predicates showed how to get at the third sibling child node of the context
node. If your goal were to get the third and fourth child sibling nodes, you could use one of the
following statements:
child::sibling[position() >= 3]
child::sibling[position() > 2]
child::*[position() = 3 or position() = 4]
All location steps in an XPath expression will follow this syntax. We can break the syntax into
pieces: the XPath statement must first specify the type of axis to traverse. The child axis is the
default if no axis is specified. After it is on the proper axis, the node test is performed to check
whether a particular node exists. In cases where a specific node must be accessed, a predicate
can be added to the XPath expression, which acts as a filter.
04 0672320398 CH03 7/24/01 10:45 AM Page 60
Samples of using this syntax are shown later in the chapter, along with abbreviated forms that
can be used to shorten the location step framework. Before these are shown, however, it’s
important that you understand what native functions exist in the XPath recommendation.
Understanding these functions will allow you to fully leverage predicates.
XPath Functions
Many functions are available other than the position() function shown earlier. The XPath rec-
ommendation categorizes each of the predicate functions based on its purpose and functional-
ity. These categories include node-set functions, string functions, number functions, and
Boolean functions. We’ll first discuss the node-set functions.
XPOINTER, AND
Example: child::*[namespace-uri() = “http://
XPATH,
XLINK
www.someURL.com”]
You’ll notice that there is no specific node-set function to extract a namespace prefix (the me in
me:local-name for instance) should one exist on a node. The local-name() function allows
you to get the node’s name, the name() function gets the prefix and local-name together, and
the namespace-uri() function returns only the namespace URI. This certainly appears to pre-
sent a problem because knowing the prefix associated with a particular node may be a big part
of your applications, depending on the number of contributors to an XML document. Fortu-
nately, this problem can be solved by taking advantage of node-set functions used in conjunc-
tion with XPath string functions.
XPOINTER, AND
a value of 0 being returned. The example returns a value
XPATH,
XLINK
of 7.
Example: string-length(“Sibling”)
normalize-space(string) This function is similar to the Trim() function in VB,
although it also replaces internal sections of whitespace
with single spaces. The example returns “How are you?”
Example: normalize-space(“ How are you? “)
translate(string, This function performs character substitutions. Characters
from,to) that exist in the first two arguments are converted to the
corresponding characters found in the third argument. This
function is best understood by seeing an example. The
example shown below will return “HOW ARE YOU?”
Example: translate(“how are you?”,”aehouwy”,
”AEHOUWY”)
The next example will return “I AM fiNE”
Example: translate(“i am fine”,”amne”,”AMNE”)
04 0672320398 CH03 7/24/01 10:45 AM Page 64
XPOINTER, AND
boolean(value) This function returns a Boolean value (true or false) depending
XPATH,
XLINK
on the value passed into the function. The conversion of a value
to Boolean normally occurs automatically as needed. However,
the boolean() function is useful to explicitly convert a value to a
Boolean when necessary. For example, if you have a node named
customerExists that contains the text “true,” you can convert this
value from a string to a Boolean by using the following syntax:
Example: boolean(/root/customerName/customerExists)
To convert a 0 (false) or 1 (true) to a Boolean, use the fol-
lowing syntax:
Example: boolean(1)
not(boolean) This function returns the opposite of what is passed into it. Thus,
if a true is passed in, a false will be returned and vice versa. The
example returns a true.
Example: not(false)
true() This function returns true. This can be used when a constant
Boolean value is needed in an XPath expression.
04 0672320398 CH03 7/24/01 10:45 AM Page 66
The following are a few examples shown first with the non-abbreviated syntax and then fol-
lowed by the abbreviated syntax. Some of the examples include more than two XPath expres-
sions to help you see other ways of accomplishing the same task. The examples are based on
the following XML document:
<?xml version=”1.0”?>
<golfers>
<golfer skill=”excellent” handicap=”4” clubs=”Taylor Made” id=”1111”>
<name>
<firstName>Heedy</firstName>
<lastName>Wahlin</lastName>
</name>
<favoriteCourses>
<course city=”Pinetop” state=”AZ” name=”Pinetop Lakes CC”/>
<course city=”Phoenix” state=”AZ” name=”Ocotillo”/>
<course city=”Snowflake” state=”AZ” name=”Silver Creek”/>
</favoriteCourses>
</golfer>
<golfer skill=”moderate” handicap=”8” clubs=”Taylor Made” id=”2222”>
<name>
<firstName>Dan</firstName> 3
<lastName>Wahlin</lastName>
XPOINTER, AND
</name>
<favoriteCourses>
XPATH,
XLINK
<course city=”Pinetop” state=”AZ” name=”Pinetop Lakes CC”/>
<course city=”Pinetop” state=”AZ” name=”White Mountain CC”/>
<course city=”Springville” state=”UT” name=”Hobble Creek”/>
</favoriteCourses>
</golfer>
</golfers>
XPath Examples
Select the id attribute of the first golfer element:
/golfers/descendant::golfer[position()=1]/attribute::id
/golfers/golfer[1]/@id
Select all descendants of the golfer element. This includes the name and favoriteCourses
elements:
/golfers/descendant::golfer/*
//golfer/*
/golfers/golfer/*
04 0672320398 CH03 7/24/01 10:45 AM Page 68
Select the name attribute of the third course element associated with the second golfer element:
/golfers/child::golfer[position()=2]/child::favoriteCourses/
➥child::course[position()=3]/attribute::name
/golfers/golfer[2]/favoriteCourses/course[3]/@name
//golfer[2]/favoriteCourses/course[3]/@name
Select the first golfer element and all children. This selects the name and favoriteCourses
elements:
/golfers/child::golfer[position()=1]/child::*
/golfers/golfer[1]/*
Select the second golfer element’s course element having a name attribute equal to the first
golfer element’s first course element name attribute (a little confusing unless you break it
down into steps):
/golfers/child::golfer[position()=2]/child::favoriteCourses/child::course/
➥attribute::name[. =
/golfers/child::golfer[position()=1]/child::favoriteCourses/
➥child::course[position()=1]/attribute::name]
/golfers/golfer[2]/favoriteCourses/course/@name[. = /golfers/golfer[1]/
➥favoriteCourses/course[1]/@name]
Select the last course element’s name attribute that is located under the second golfer
element:
/golfers/child::golfer[position()=2]/favoriteCourses/course[last()]/@name
//golfer[2]//course[last()]/@name
/golfers/golfer[2]/favoriteCourses/course[last()]/@name
Select the city attribute of all course elements that have a name attribute starting with the
letter “P”:
/golfers/child::golfer/child::favoriteCourses/child::course[starts-with
➥(@name,’P’)]/attribute::city
/golfers/golfer/favoriteCourses/course[starts-with(@name,’P’)]/@city
Select the first golfer element’s skill attribute and capitalize it:
translate(/golfers/child::golfer[position()=1]/attribute::skill,
➥‘abcdefghijklmnopqrstuvwxyz’,’ABCDEFGHIJKLMNOPQRSTUVWXYZ’)
translate(/golfers/golfer[1]/@skill,’abcdefghijklmnopqrstuvwxyz’,
➥‘ABCDEFGHIJKLMNOPQRSTUVWXYZ’)
04 0672320398 CH03 7/24/01 10:45 AM Page 69
After seeing the previous XPath statements, you may be wondering how you can test them to
see if they actually work. You may also want to practice creating some of your own XPath
statements. Fortunately, an excellent browser-based tool for testing XPath statements was
created by Aaron Skonnard of DevelopMentor. The tool can be downloaded from http://
staff.develop.com/aarons/xmllinks.htm. Figure 3.1 shows an example of the tool in
action.
XPOINTER, AND
XPATH,
XLINK
FIGURE 3.1
Using the XPath Interactive Expression Builder.
XPointer supports addressing into the internal structures of XML documents. It allows for
examination of a document’s hierarchical structure and choice of its internal parts based on
various properties, such as element types, attribute values, character content, and relative posi-
tion. In particular, it provides for specific reference to elements, character strings, and other
parts of XML documents, whether or not they bear an explicit ID attribute.
Many of the concepts mentioned in this statement strongly resemble functionality already
available in the XPath language, which may lead you to believe that much is duplicated
between the two. However, this is not the case. XPointer simply extends XPath’s functional
utility, as you’ll see in the following sections. Your current XPath knowledge will be applicable
to many XPointer concepts.
XPointer Basics
At this point you may be wondering what the difference is between XPath and XPointer.
Because both seem to allow access to specific items found within an XML document, can
XPointer be used for something different? Obviously the answer to this question is “yes,” given
all the work that has gone into creating the language. XPointer differs from XPath because it
provides a mechanism for accessing specific content, referred to as document fragments,
located in local or remote documents. This content isn’t limited just to nodes. XPointer even
allows individual characters in a text string to be selected.
Imagine having an XML document containing research data that is composed of three sections,
including an introduction, body, and conclusion. The body and conclusion portions of the doc-
ument do not exist within this XML document. They are located externally within two XML
documents that contain information other than simply body or summary text.
Using XPath alone, there is no mechanism for gaining access to the body and summary text in
these remote documents. XPath is designed to locate specific nodes within a local XML docu-
ment. This is where XPointer comes into play. Using portions of XPath syntax, XPointer
allows the body and summary text sections to be gathered from the remote documents and
placed into the current XML document. All this can be done without having to load the entire
remote document (or documents in this case). Comparing this functionality to HTML, combin-
ing these languages allows you to link to a specific area of a document and “grab” its content
without having to load the entire page and then scroll to the content as is done with HTML
anchors.
The capability to access data down to the individual character level opens up a whole new
world for data sharing and exchange. Before getting too much further into the details, let’s
cover a few key XPointer definitions:
04 0672320398 CH03 7/24/01 10:45 AM Page 71
Term Definition
sub-resource The portion of the XML document that XPointer identifies. Although
the entire XML document would be considered the resource, the
portion being accessed by XPointer would be the subresource.
point The W3C defines a point simply as “A position within XML infor-
mation.” A point may represent a node within an XML document or
simply a specific location within a node’s XML character data. The
combination of a container node and index value define a point’s
location. A point may be a position before any character or may pre-
cede or follow a node. A point can never exist on a character,
though, only before or after it.
As an example, the “T” character in the following document frag-
ment has a container of type element and has an index of 0. The “e”
would have an index of 1 and the “d” character an index of 2:
<golfer>
<firstName>Ted</firstName>
</golfer>
character point A point with a container node that has no child nodes. Examples 3
include a point within text, comments, processing instructions, and
XPOINTER, AND
so on.
XPATH,
XLINK
node point A point with a container node that has child nodes.
range A selection of XML content located between two end points. When
you highlight a section of text in a program (such as Word) using
the cursor, the selected area could be considered a range because it
has starting and ending points.
collapsed range A range that has equal start and end points. For example, if we start
a point at character three and end a point at character three, the
ranged is considered to be collapsed.
location Similar to a node in XPath. However, because XPointers can begin
in one paragraph and end in another and do not have to specify
nodes in particular, a location can be a node, point, or range.
location-set This is similar to a node-set created by an XPath expression.
However, aside from including nodes, a location-set can also
include points and/or ranges.
singleton This term is reserved for situations where one range, string range, or
single node is located by an XPointer. Multiple areas of XML con-
tent identified by an XPointer are not considered to be singletons.
fragment identifier An XPointer identifier (expression) that has an escaped URI.
Escaped refers to replacing characters such as < with their URI
escape value, which would be < in this case.
04 0672320398 CH03 7/24/01 10:45 AM Page 72
Points and ranges are used when working with XPointer expressions. Points determine where
to start and end a search for XML content within a document, and a range contains the XML
content located between two points. The syntax to create XPointer expressions using two
points is as follows:
http://www.someURL.com/someDOC.xml#xpointer(<point1> to <point2>)
This syntax would link to the range specified between point1 and point2 and load the entire
document. You’ll notice that this is similar to how the HTML anchor currently works, although
XPointer allows for much more flexibility, as you’ll see in the next few sections. After parsers
support this feature, you’ll be able to pick out a section of XML within a remote document
with pinpoint accuracy.
XPointer Functions
The additional functions available in the XPointer language along with their corresponding
descriptions are listed in Table 3.6. One interesting point about these functions is that they can
be called after a / character in a location step (that is, node/function()). This is different
from the XPath language where calling a function after the / character would normally result
in the parser raising an error (exceptions to this exist, such as the count() and sum() func-
tions to name just two).
XPOINTER, AND
will start just after the “L” character (four characters in)
XPATH,
and contain the five characters that come after the fourth
XLINK
(represented by [4]) “XML” string:
Example: string-range(//title,”XML”,4,5)[4]
range(location-set) This function returns ranges that match up with the loca-
tions specified in the location-set argument. The example
would return ranges for all folder elements that have an
attribute named path starting with the letter “D.” The
range starts just before the folder node’s beginning tag
and ends just after its ending tag:
Example: range(//folder[starts-with(@path,”D”)])
range-inside(location-set) This function returns ranges that match up with the con-
tent specified in the location-set argument. This is similar
to the innerText property found in DHTML, which also
returns the text between a start and end tag. It differs
from the range() function in that it includes only a
node’s content, not the node and its content. The example
would return ranges for all folder elements that have an
attribute named path starting with the letter “D.” The
range starts just after the folder node’s beginning tag and
ends just before its ending tag:
04 0672320398 CH03 7/24/01 10:45 AM Page 74
XPointer Errors
Errors in XPointer can be handled differently than errors in XPath. In situations where an
XPath expression finds no matching locations within the XML document, an empty node-set is
returned and no error is raised. However, XPointer must be stricter with error handling because
it allows access to remote documents. XPointer is required to raise an error if a fragment iden-
tifier (expression) returns no results. The following is a summary of the three errors that can be
associated with XPointer and their associated description:
Error Description
Syntax Error This error occurs when an XPointer expression (also
called a fragment identifier) contains incorrect syntax.
Resource Error This error occurs when a resource document does not
contain well-formed XML. The fragment identifier
(XPointer expression) may be correct but be unable to
create a point or range because of resource document
problems.
Subresource Error This error occurs when an XPointer expression is syntac-
tically correct, the resource contains well-formed XML, 3
but no locations are returned. As mentioned, this type of
XPOINTER, AND
error does not occur in XPath, because empty node-sets
XPATH,
are acceptable there.
XLINK
XPointer Examples
As the XPointer language is moved to the W3C recommended status, more and more examples
of using it with supporting parsers will become available. Until then, here are a few examples of
using XPointer. The examples are prefixed by a remote resource name of www.someURL.com:
The #/1/3/4 syntax tells XPointer to go to remoteDocument.xml and access the first element
found there. After finding this element, find its third child element. Now choose this element’s
fourth child element.
The following example will pull the content between the first and third sibling nodes:
http://www.someURL.com/remoteDocument.xml#xpointer(//father/sibling[1] to
➥//father/sibling[3])
The next example will return all ranges within the /golfers/golfer/name context that contain
a substring equal to “Joe”:
http://www.someURL.com/remoteDocument.xml#xpointer(string-range(/golfers/
➥golfer/name,”Joe”))
Finally, the following document will first try to find a golfer element’s fourth name node. If
that location cannot be found, it will try to find the last name node:
http://www.someURL.com/remoteDocument.xml#xpointer(//golfer/name[4])
➥xpointer(//golfer/name[last()])
You may recall a short discussion we had concerning HTML linking limitations at the begin-
ning of this chapter. Although HTML links work quite well in a browser, some of the limita-
tions found in the HTML link include the following:
• HTML allows links only between two resources.
• HTML links have to be embedded in the originating link’s file. This can cause mainte-
nance headaches.
• HTML anchors can help locate specific information within a document but require that
the entire page be loaded. This wastes bandwidth.
• HTML links are unidirectional. They can point only in one direction.
• The HTML link has few attributes for customizing linking capabilities based on different
linking needs.
• Updating a target document with anchors is not possible without having “write” access
to that document.
• HTML links require specific element tags to work (<a> for example). This makes it diffi-
cult to add linking capabilities to other elements.
A few of these limitations are addressed by the XPointer language because it allows specific 3
content fragments to be accessed in remote XML documents. Although this is a great step for-
XPOINTER, AND
ward, the old HTML link can be improved on in many other ways. XLink strives to make these
XPATH,
XLINK
improvements a reality by adding new linking capabilities to documents that comply with the
XML version 1.0 recommendation.
XLink Basics
The XLink specification doesn’t actually mention linking different documents. Rather, it
defines a structure that consists of links between “resources.” These resources could be XML
documents, media files (images, movies, or music), database information, or any other type of
resource that needs to be referenced through a link.
Adding more functionality to any type of established item, such as the HTML link, is often-
times associated with an overall increase in complexity. This is not necessarily the case with
XLink. After you understand its keywords, elements, attributes, and functionality, you’ll see
that it looks just like regular XML.
Although the XLink language allows you to define links the same way as you do in HTML, it
does bring with it more advanced attribute and element definitions that help in linking two,
three, or more resources in a uniform manner. Understanding the various attributes and defini-
tions that come with the XLink language is important to leverage its linking power.
04 0672320398 CH03 7/24/01 10:45 AM Page 78
Before learning about the attributes and elements that exist in XPath, let’s take a look at some
examples of what XPath syntax looks like. First let’s write out the syntax for what is coined a
“simple link.” A simple link functions the same as a link found within an HTML page:
<golfer xmlns:xlink=”http://www.w3.org/1999/xlink/”>
<name xlink:type=”simple” xlink:href=”http://www.someURL.com/row.aspx”>
John Doe
</name>
</golfer>
The following is an example of an extended link containing four different resources. This type
of linking is not possible using HTML’s anchor tag:
<xlink:extended
xmlns:xlink=”http://www.w3.org/1999/xlink/”
role=”foursome”
title=”Golfing foursome”
>
<xlink:locator href=”dad.xml”
role=”golfer1”
title=”First golfer in foursome”
/>
<xlink:locator href=”aaronhorne.xml”
role=”golfer2”
title=”Second golfer in foursome”
/>
<xlink:locator href=”toddwahlin.xml”
role=”golfer3”
title=”Third golfer in foursome”
/>
<xlink:locator href=”michellehorne.xml”
role=”golfer4”
title=”Fourth golfer in foursome”
/>
<xlink:arc from=”golfer1”
to=”golfer2”
actuate=”onRequest”
show=”embed”
/>
<xlink:arc from=”golfer3”
to=”golfer4”
actuate=”onRequest”
show=”embed”
/>
</xlink:extended>
04 0672320398 CH03 7/24/01 10:45 AM Page 79
I’ll defer an in-depth discussion of the different elements and attributes being used here until
later in the chapter. You can see, however, that after you understand a few basic concepts con-
cerning new elements and attributes defined in the XLink specification, implementing the
XLink language isn’t much different than working with normal XML documents.
XPOINTER, AND
Example: <xlink:arc from=”resource1” to=”resource2”/>
XPATH,
XLINK
Extended link An extended link associates many local and/or remote resources
together. The link is considered inline if any of the resources are
local and considered out-of-line if none are local.
Inline link Defined by the W3C as “A link where some content in the link-
ing element serves, by virtue of its presence inside the linking
element, as a participating resource.” Use of the <a> tag in
HTML is considered an inline link.
Locator Data used to identify a resource in a link. Identification occurs
by specifying a URI or other type of identity.
Linkbase A file external of any resource that contains an extended link.
This type of file is similar to an include file in ASP.NET because
it helps maintain specific information referenced by many
resources in one location.
Multidirectional link A multidirectional link can be started by any of the resources
participating in the link. As such, the HTML link would be
excluded from this definition because it can initiate only a one-
way link (hitting the Back button doesn’t count).
04 0672320398 CH03 7/24/01 10:45 AM Page 80
Now that you’re familiar with a few of XLink’s definitions and keywords, let’s take a look at
some attributes that are used in building simple and extended links.
XLink Attributes
The XLink language specifies several attributes that add various linking capabilities. A listing
of these attributes with their corresponding description can be found in Table 3.8.
XPOINTER, AND
xlink:show This determines how content identified by a link will be shown.
XPATH,
XLINK
The possible values are replace, embed, new, other, and none.
The replace value functions in the same manner as linking
between two pages in HTML, whereas the embed value would be
similar to the function the <img> tag element performs.
xlink:actuate The actuate attribute specifies how the link should be traversed
from a timing perspective. Rather than always being triggered by
human interaction, the link can be set to be triggered by an appli-
cation. Possible values include onRequest, onLoad, other, and
none.
xlink:to This attribute is used only with an arc element in an extended
link to specify the end point of a link. Its value is equal to the
label attribute on a resource or locator type element.
xlink:from This attribute is used only with an arc element in an extended
link to specify the start point of a link. Its value is equal to the
label attribute on a resource or locator type element.
04 0672320398 CH03 7/24/01 10:45 AM Page 82
The xlink:type attribute is specified as “simple” and the xlink:href lists the link URI. This
method of declaring a link is more efficient than the current HTML linking implementation. To
understand why, imagine trying to add linking capability to a <p> tag in HTML without wrap-
ping it with the <a> and </a> tags (or using scripting). Using attributes allows a link to be
added to any element quite easily.
Although you learned a little about XLink attributes earlier, let’s take a look at two interesting
attributes that should prove to be very useful in applications that implement XLink in the
future. The actuate attribute can take on values of onLoad, onRequest, other, and none. The
onRequest value means that the link is traversed when the user requests it. The onLoad value is
used to traverse a link immediately after a document completes loading. When the show
attribute is equal to embed and actuate is equal to onLoad, a useful way of embedding content
from outside resources can be accomplished. When combined with XPointer, these technolo-
gies could be used to create the research XML document discussed earlier that linked to intro-
duction, body, and summary sections located in remote documents.
04 0672320398 CH03 7/24/01 10:45 AM Page 83
Resource 3 Resource 4
XPOINTER, AND
XPATH,
XLINK
Resource 1 Resource 2
FIGURE 3.2
Extended link relationships.
At first glance, this figure may look very similar to simple links between resources, as in
HTML. However, the extended link includes all these resources in a relationship and then spec-
ifies how the links should be traversed. Listing 3.2 shows how these links could be written
using extended link XPath syntax. It’s important to know that the extendLink and loc element
names were chosen to make the sample easier to understand. These element names are not part
of the XLink specification. In fact, any element name could be used.
04 0672320398 CH03 7/24/01 10:45 AM Page 84
The extended element type shown in Listing 3.2 acts as a container for four different resource
links. It contains some of the same attributes you saw in the simple element type shown ear-
lier, and it also declares the XLink qualified namespace. Inside this container are four locator
elements that specify the URI to each resource. Going back to Figure 3.2, the small boxes
located on each resource would represent that resource’s locator.
Although the code shown in Listing 3.2 specifies the locators for each resource and groups
each resource in an extended container, it does not say how links between the resources should
be traversed. Should Resource 1 link to Resource 3? Should Resource 4 link to Resource 3?
The listing doesn’t mention anything about the way the resources should be linked.
To accommodate the need for specifying how links should be traversed, the XLink language
introduces the arc concept. An arc can be thought of as a traversal path that specifies how to
link from one resource and to another. Listing 3.3 adds on to Listing 3.2’s code by adding
information about link traversals through the use of arc element types.
XPOINTER, AND
By specifying the arc path, you now know the locations of four resources as well as how each
link between the resources should be traversed. The arc elements listed previously tell the
XPATH,
XLINK
extended link that resource1 links to resource2, which links to resource3, which links to
resource4. If you had wanted resource4 to link back to resource1, you could have applied
another XLink type attribute to an element and specified the additional arc path using the from
and to attributes.
Any variety of arc paths can be specified as long as all paths are unique. All this is done with-
out having to actually add a physical link inside of resource3 that goes to resource4, as is
the case when you link to a resource that you have no control over. Exactly how will
resource3 link to resource4 if the link isn’t physically embedded in resource3? To answer
this question completely, we will have to wait for the first XLink-capable applications to
appear on the scene and analyze how this feature is implemented.
One interesting point made in the XLink specification is that if a from or to attribute is miss-
ing in an arc type element, an arc will be created in the appropriate direction to all locator type
elements with label attributes located within the extended link grouping. To clarify this less
intuitive concept, the W3C provides the following example:
<extendedlink xlink:type=”extended” xmlns:xlink=”http://www.w3.org/1999/xlink”>
<loc xlink:type=”locator” xlink:href=”...” xlink:label=”parent”
➥xlink:title=”p1”/>
04 0672320398 CH03 7/24/01 10:45 AM Page 86
Based on each locator type’s title attribute, the following arcs would be assumed because there
are missing from and to attributes in the arc type element:
p1-c1, p1-c2, p1-c3, p2-c1, p2-c2, p2-c3, c1-c1, c1-c2, c1-c3, c2-c1, c2-c2, c2-c3,
c3-c1, c3-c2, and c3-c3
As you can see, this rule causes a type of cross-join to occur that involves each locator type
element. Although all possible arcs are pursued, the uniqueness of each arc is maintained.
The extended link automatically allows links between resources to be organized and grouped.
For this extended link to be useful, it would need to be embedded in one of the resources. This
is called an inline extended link because the resource that contains the embedded link informa-
tion would be editable, in contrast to a third-party read-only resource. After the extended link
is inserted, the relationships between the different resources specified in the locator type ele-
ments can be managed.
Resource 3 Resource 4
External
Linkset
Resource 1 Resource 2
FIGURE 3.3
An out-of-line extended link.
For an external linkset document to be used, a resource needs to know where the external 3
linkset document is located. This is accomplished by placing code similar to the following into
XPOINTER, AND
an inline resource:
XPATH,
XLINK
<basesloaded xlink:type=”extended” xmlns:xlink=”http://www.w3.org/1999/xlink”>
<startrsrc xlink:type=”locator” xlink:label=”spec” xlink:href=”spec.xml”/>
<linkbase xlink:type=”locator” xlink:label=”linkbase” xlink:href=
➥”linkbase.xml”/>
<load xlink:type=”arc” xlink:from=”spec” xlink:to=”linkbase”
xlink:actuate=”onLoad”
xlink:arcrole=”http://www.w3.org/1999/xlink/properties/linkbase”
/>
</basesloaded>
Maintenance of links suddenly becomes much easier through the use of linkbases and external
linksets.
Summary
In this chapter we covered a lot of technologies related to XML. Although the XPointer and
XLink languages have yet to be implemented fully, they are promising technologies that will
make developing with XML even more powerful. In Chapters 6 and 7, you will see how useful
the XPath language can be to access data contained within an XML document using the DOM
or XSLT. However, before jumping into those chapters, Chapter 4 takes a look at XML DTDs
and schemas.