This tip introduces XPointer and discusses how to use it in conjunction with XLink to refer to a specific part of another XML document.
In this tip, I want to build on what I showed you in my Using XML and XLink tip. XLink, while useful, only allows you to refer to another document. It is much more common to want to refer to a specific part of another document. With XPointer, this becomes very simple. It's somewhat analogous to using named anchors in HTML, and can be accomplished by using XPointer in conjunction XLink. The two specifications, which are intended to work together, build naturally upon each other. This tip will describe how to achieve this more specific linking using XPointer. To refer to a specific part of a document, you should first take a look at the target document you're going to link to. Ensure that this document uses id attributes on each element that you may want to link to. This will make the linking and pointing much easier. Listing 1 shows a set of guitars that luthier Dana Bourgeois makes; notice that each type element contains an ID attribute, which specifies the guitar type. Note: For the sake of clarity, the URL for Bourgeois Guitars has been changed from the actual URL, http://www.bourgeoisguitars.com, to a shorter URL, http://bg.com. This makes the code listings much easier to read. If you want to see this document in action, change the references from http://bg.com back to http://www.bourgeoisguitars.com. Listing 1. A listing of Bourgeois guitars <?xml version="1.0"?> <guitarTypes xmlns="http://bg.com"> <type model="OM" ID="OM"> <picture url="http://bg.com/images/vvOM.jpg" /> <description>Small bodied orchestra model.</description> </type> <type model="D" ID="D"> <picture url="http://bg.com/images/ricky%20skaggs%20model.jpg" /> <description> Bluegrass powerhouse in a standard dreadnought shape. </description> </type> <type model="slopeD" ID="slopeD"> <picture url="http://bg.com/images/slope%20d,%20custom%20version.jpg" /> <description> Slope shouldered dreadnought, perfect for vocal accompaniment. </description> </type> </guitarTypes>
For this tip, assume that this document is available at http://bg.com/guitars.xml. Instead of referencing the entire document, XPointer allows you to link to specific portions of the document. For example, a guitar store might want to link to just the guitar type or types that they currently have in stock. Remember the xlink:href attribute from the XLink tip? The value supplied to that attribute was the target of an XLink. To refer to a specific part of the page, though, you can add a pound sign (#) and an XPointer expression to these URLs. For example, the expression xpointer(id("slopeD")) refers to the type element in the target document, with the ID value of "slopeD". Adding this to the original XLink expression, you would come up with the following URL: http://bg.com/guitars.xml#xpointer(id("slopeD")). Using this expression, you could refer to the XML shown in Listing 1, and then to the Slope D model guitar described in that document. Easy enough, right? Let me show you a modified version of the XML document I introduced in the XLink tip describing several guitars; this modified version refers to the type of guitar for each specific model, all through XLink and XPointer references.
Listing 2. Using XPointer in an XML document
<?xml version="1.0"?> <guitars xmlns="http://www.newInstance.com/about/guitars" xmlns:xlink="http://www.w3.org/1999/xlink"> <guitar luthier="Bourgeois" xlink:type="simple" xlink:href= "http://bg.com/guitars.xml#xpointer(id('OM'))" > <description xlink:type="simple" xlink:href= "http://newInstance.com/guitar/bgOM/pics/bougOM_front_full.jpg" xlink:actuate="onLoad" xlink:show="embed"> This is a real beauty in a small body. Although this is an OM, I use it for flatpicking bluegrass as well as for producing some beautiful fingerstyle sounds. </description> </guitar> <guitar luthier="Bourgeois" xlink:type="simple" xlink:href= "http://bg.com/guitars.xml#xpointer(id('D'))" > <description xlink:type="simple" xlink:href= "http://newInstance.com/guitar/bgD150/pics/bougd150_con_rim2.jpg" xlink:actuate="onLoad" xlink:show="embed"> Here's the holy grail in process. Dana Bourgeois is building this Brazilian rosewood and adirondack bluegrass monster right now. You'll know it's finished when you hear a run and your windows shatter! </description> </guitar> </guitars>
Now my document can reference the XML content that Dana Bourgeois keeps about his guitars. This is particularly handy if Dana decided to update or change this information. If he changes the XML document, I don't have to worry about it; my document stays current because it simply links to his updated information.
One thing to watch for though: In the code above, I had to escape the quotation marks within the XPointer expression by using & instead of an ampersand ("&"). This makes for a rather long URL to link to, and long URLs can lead to hard-to-find typos. Luckily for us, XPointer allows a handy shorthand form when linking to an element with an ID tag (such as the type element). Instead of using the xpointer(id("D")) form, you can use the value of the ID to target. For example, you could use simply "D". So I can simplify the document in Listing 2 to that shown in Listing 3, which makes for a much cleaner link syntax. All the escaped ampersands are gone, resulting in an easier document for both reading and debugging. Listing 3. Using XPointer shorthand for ID links
<?xml version="1.0"?> <guitars xmlns="http://www.newInstance.com/about/guitars" xmlns:xlink="http://www.w3.org/1999/xlink"> <guitar luthier="Bourgeois" xlink:type="simple" xlink:href="http://bg.com/guitars.xml#OM" > <description xlink:type="simple" xlink:href=" http://newInstance.com/guitar/bgOM/pics/bougOM_front_full.jpg" xlink:actuate="onLoad" xlink:show="embed"> This is a real beauty in a small body. Although this is an OM, I use it for flatpicking bluegrass as well as for producing some beautiful fingerstyle sounds. </description> </guitar> <guitar luthier="Bourgeois" xlink:type="simple" xlink:href="http://bg.com/guitars.xml#D" > <description xlink:type="simple" xlink:href=" http://newInstance.com/guitar/bgD150/pics/bougd150_con_rim2.jpg" xlink:actuate="onLoad" xlink:show="embed"> Here's the holy grail in process. Dana Bourgeois is building this Brazilian rosewood and adirondack bluegrass monster right now. You'll know it's finished when you hear a run and your windows shatter! </description> </guitar> </guitars>
In addition to this simpler listing with an abbreviated form of links, you can point to elements that are relative to other elements. As an example of this, in Listing 4 I have changed my description elements to point to the image specified in the bourgeois.xml remote file. Let's see how this is accomplished.
In Listing 4 you can see that the first step is to locate a specific element in the referenced document. That element serves as the reference point for the relative expression appended to it. In this example, the descendant of that element (specified by the descendant keyword), named "picture" (from Listing 1), is specified. The final target of the link, then, is the value of the attribute of that element, named "url". I know that's a mouthful, but if you take it step by step, it turns out to be fairly straightforward. You should notice in Listing 4 that I did not use the shorthand form of ID links that I talked about in the last section. That's because using that form of ID linking only allows for a direct link; without the longer form of ID linking, you can't have any further linking (such as the child-traversing reference in Listing 4). For more information on the huge variety of options that XPointer offers, check out the XPointer specification online (see Resources). You may also want to check out XPath, which defines even more complex path expressions; the specification for XPath is also available online (see Resources). I know this is only an introduction, but now you can tell your friends and family how much more you know about XPointer, XLink, and XPath than they do! Try it out, read the specs, and watch for upcoming browser support for these XML-related specifications. |