XQuery
Priscilla Walmsley (pwalmsley@datypic.com)
ISBN: 0596006349
1st edition, , 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