July 22, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

What's New in XPath 2.0?

  • April 23, 2004
  • By Steven Holzner
  • Send Email »
  • More Articles »

The some and every Expressions

You can use a rudimentary form of a conditional expression in XPath 1.0—for example, this expression, as used in a predicate:

/planets/planet[1]/name = "Mars"

would be true if any <name> element in the first <planet> element had the text "Mars".

XPath 2.0 extends this kind of checking. You can either perform the same test in XPath 2.0 using the same syntax, or you can use the some expression. Using the some expression means that at least one item in a sequence satisfies an expression given with a satisifies predicate, like this:

some $variable in /planets/planet[1]/name satisfies $variable = "Mars"

In this case, this expression returns true if at least one <name> element in the first <planet> element has the text "Mars".

You can also perform other kinds of tests here, such as this expression, which is true if any <radius> element in the first <planet> element contains a value greater than 2000:

some $variable in /planets/planet[1]/radius satisfies $variable > 2000

You can also insist that every <radius> element in the first <planet> element contains a value greater than 2000 if you use the every expression instead of some, like this:

every $variable in /planets/planet[1]/radius satisfies $variable > 2000

Unions, Intersections, and Differences

In XPath 1.0, you could use the | operator to create the union (that is, the combination) of two sets, as in this case, where we're matching attributes and nodes in an XSLT template:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.1" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>

 <xsl:template match="distance[preceding::*/name='Mercury']">
  <distance>This planet is farther than Mercury from the sun.</distance>
 </xsl:template>
  
 <xsl:template match="@*|node()">
  <xsl:copy>
   <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
 </xsl:template>

</xsl:stylesheet>

In XPath 2.0, you can create not only unions like this, but also intersections, which contain all the items two sequences have in common, and differences, which contain all the items that two sequences have that are not in common.

Let's take a look at how this works. For example, to get the same result as the previous XPath 1.0 example, we can use the union operator in XPath 2.0:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>

 <xsl:template match="distance[preceding::*/name='Mercury']">
  <distance>This planet is farther than Mercury from the sun.</distance>
 </xsl:template>
  
 <xsl:template match="@* union node()">
  <xsl:copy>
   <xsl:apply-templates select="@* union node()"/>
  </xsl:copy>
 </xsl:template>

</xsl:stylesheet>

In addition, XPath 2.0 introduces the intersect operator, which returns the intersection of two sequences (that is, all those items they have in common). For example, if the variable $planets holds a sequence of <planet> elements, we could create a sequence of <planet> elements that $variable has in common with the planets in our planetary data document, like this:

$planets intersect /planets/planet

To find the difference between two sequences, you can use the except operator. For example, if you wanted to find all items in $planets that were not also in the sequence returned by /planets/planet, you could use except this way:

$planets except /planets/planet

Here's something else that's new in XPath 2.0—you can now specify multiple node tests in location steps. Here's an example:

planets/(mass|day)/text()

Here's what that would look like in XPath 1.0:

planets/mass/text() | planets/day/text()

And, as already mentioned, there are many new functions coming up in XPath 2.0. One of the specific tasks that W3C undertook in XPath 2.0 was to augment its string-processing capabilities. Accordingly, you'll find more string functions in XPath 2.0, including upper-case, lower-case, string-pad, matches, replace, and tokenize.

Note in particular the matches, replace, and tokenize functions—these functions use regular expressions, a powerful new addition to XPath. Regular expressions let you create patterns to use in matching text. Regular expression patterns use their own syntax—for example, the pattern \d{3}-\d{3}-\d{4} matches U.S. phone numbers, like 888-555-1111. Being able to use regular expressions like this is very powerful because you can match the text in a node to the patterns you're searching for.

Comments

You can also create XPath 2.0 comments using the delimiters (: and :). Here's an example:

(: Check for at least one planet with the name Mars :)
some $variable in /planets/planet[1]/name satisfies $variable = "Mars"

Comments may be nested.

That completes our XPath 2.0 overview—now you've gotten an idea of the kinds of things that are different in XPath 2.0. Besides what we've seen in these few examples, there are plenty of additional new expressions coming up, such as cast, treat, and instance of. My next article will provide you with some XPath 2.0 examples.

About the Author

Steven Holzner is an award-winning author who has been writing about XML topics such as XSLT as long as they've been around. He's the author of XPath Kick Start : Navigating XML with XPath 1.0 and 2.0 (published by Sams Publishing), and has written 67 books, all on programming topics, selling well over a million copies. His books have been translated into 16 languages around the world and include a good number of industry bestsellers. He's a former contributing editor of PC Magazine, graduated from MIT, and received his Ph.D. at Cornell. He's been on the faculty of both MIT and Cornell, and also teaches corporate seminars around the country.



Page 3 of 3



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel