Datypic Logo
XQuery

XQuery

Priscilla Walmsley (pwalmsley@datypic.com)

ISBN: 0596006349

1st edition, 2007, O'Reilly Media, Inc.

Chapter 15: Principles of query design

Example 15-1. Making use of whitespace
Less clear query
for $product in doc("catalog.xml")//product return
<product><number>{$product/number}</number>
<price>{for $price in doc("prices.xml")//prod
where $product/number = $price/@num
return $price/price}</price>
</product>
More clear query
for    $product in doc("catalog.xml")//product
return <product>
         <number>{$product/number}</number>
         <price>{for    $price in doc("prices.xml")//prod
                 where  $product/number = $price/@num
                 return $price/price}</price>
       </product>
Example 15-2. Documenting a function with xqdoc
declare namespace functx = "http://www.functx.com";
(:~
: The <b>functx:substring-after-last</b> function returns the part
: of <b>$string</b> that appears after the last occurrence of
: <b>$delim</b>. If <b>$string</b> does not contain
: <b>$delim</b>, the entire string is returned.
:
: @param $string the string to substring
: @param $delim the delimiter
: @return the substring
:)
declare function functx:substring-after-last
($string as xs:string?, $delim as xs:string) as xs:string?
 {  ...   };
Useful function: if-absent (see also functx:if-absent)
declare namespace functx = "http://www.functx.com";
declare function functx:if-absent (
  $node as node()?, $value as xs:anyAtomicType) as xs:anyAtomicType*
{
  if ($node)
  then data($node)
  else $value
};
(: Example call :)
for $prod in doc("prices.xml")//prod
return $prod/price - functx:if-absent($prod/discount, 0)
Useful function: if-empty (see also functx:if-empty)
declare namespace functx = "http://www.functx.com";
declare function functx:if-empty (
  $node as node()?, $value as xs:anyAtomicType) as xs:anyAtomicType*
{
  if (string($node) != "")
  then data($node)
  else $value
};
(: Example call :)
for $prod in doc("prices.xml")//prod
return $prod/price - functx:if-empty($prod/discount, 0)
Example 15-3. Avoid re-evaluating the same expression
Less efficient query
if (doc("prices.xml")/prices/priceList/prod[price < 30])
then <bargain-bin>{
       doc("prices.xml")/*/priceList/prod[price < 30]
     }</bargain-bin>
else ()
More efficient query
let $bargains := doc("prices.xml")/prices/priceList/prod[price < 30]
return if ($bargains)
       then <bargain-bin>{$bargains}</bargain-bin>
       else ()
Example 15-4. Avoid unnecessary sorting
Less efficient query
let $doc := doc("catalog.xml")
return $doc//number | $doc//name
More efficient query
unordered {
  let $doc := doc("catalog.xml")
  return $doc//(number|name)
}
Example 15-5. Avoid expensive path expressions
Less efficient query
doc("catalog.xml")//number
More efficient query
doc("catalog.xml")/catalog/product/number
Example 15-6. Use predicates instead of where clauses
Less efficient query
for $prod in doc("catalog.xml")//product
where $prod/@dept = "ACC"
order by $prod/name
return $prod/name
More efficient query
for $prod in doc("catalog.xml")//product[@dept = "ACC"]
order by $prod/name
return $prod/name
Datypic XQuery Services