XQuery
Priscilla Walmsley (pwalmsley@datypic.com)
ISBN: 0596006349
1st edition, , O'Reilly Media, Inc.
Chapter 9: Advanced queries
declare namespace functx = "http://www.functx.com"; declare function functx:add-attribute ($element as element(), $name as xs:string, $value as xs:anyAtomicType?) as element() { element { node-name($element)} { attribute {$name} {$value}, $element/@*, $element/node() } };
declare namespace functx = "http://www.functx.com"; declare function functx:remove-attributes ($element as element(), $names as xs:string*) as element() { element { node-name($element)} { $element/@*[not(name() = $names)], $element/node() } };
declare namespace functx = "http://www.functx.com"; declare function functx:remove-attributes-deep ($element as element(), $names as xs:string*) as element() { element { node-name($element)} { $element/@*[not(name() = $names)], for $child in $element/node() return if ($child instance of element()) then functx:remove-attributes-deep($child, $names) else $child } };
declare namespace functx = "http://www.functx.com"; declare function functx:remove-elements-deep ($element as element(), $names as xs:string*) as element() { element {node-name($element)} {$element/@*, for $child in $element/node() return if ($child instance of element()) then if ($child[name() = $names]) then () else functx:remove-elements-deep($child, $names) else $child } };
declare namespace functx = "http://www.functx.com"; declare function functx:remove-elements-not-contents ($element as element(), $names as xs:string*) as element() { element {node-name($element)} {$element/@*, for $child in $element/node() return if ($child instance of element()) then if ($child[name() = $names]) then $child/node() else functx:remove-elements-not-contents($child, $names) else $child } };
declare function local:change-elem-names ($nodes as node()*, $old-names as xs:string+, $new-names as xs:string+) as node()* { if (count($old-names) != count($new-names)) then error(xs:QName("Different_Number_Of_Names")) else for $node in $nodes return if ($node instance of element()) then let $newName := if (local-name($node) = $old-names) then $new-names[index-of($old-names, local-name($node))] else local-name($node) return element {$newName} {$node/@*, local:change-elem-names($node/node(), $old-names, $new-names)} else $node };
declare function local:change-elem-names ($nodes as node()*, $old-names as xs:string+, $new-names as xs:string+) as node()* { if (count($old-names) != count($new-names)) then error(xs:QName("Different_Number_Of_Names")) else for $node in $nodes return if ($node instance of element()) then let $newName := if (local-name($node) = $old-names) then $new-names[index-of($old-names, local-name($node))] else local-name($node) return element {$newName} {$node/@*, local:change-elem-names($node/node(), $old-names, $new-names)} else $node }; let $order := doc("order.xml")/order let $oldNames := ("order", "item") let $newNames := ("purchaseOrder", "purchasedItem") return local:change-elem-names($order, $oldNames, $newNames)
let $count := 0 for $prod in doc("catalog.xml")//product[@dept = ("ACC", "WMN")] let $count := $count + 1 return <p>{$count}. {data($prod/name)}</p>
for $prod in doc("catalog.xml")//product[@dept = ("ACC", "WMN")] return <p>{$prod/position()}. {data($prod/name)}</p>
for $prod at $count in doc("catalog.xml")//product[@dept = ("ACC", "WMN")] return <p>{$count}. {data($prod/name)}</p>
for $prod at $count in doc("catalog.xml")//product where $prod/@dept = ("ACC", "MEN") order by $prod/name return <p>{$count}. {data($prod/name)}</p>
let $sortedProds := for $prod in doc("catalog.xml")//product where $prod/@dept = "ACC" or $prod/@dept = "MEN" order by $prod/name return $prod for $sortedProd at $count in $sortedProds return <p>{$count}. {data($sortedProd/name)}</p>
<p>{ let $prods := doc("catalog.xml")//product let $numProds := count($prods) for $prod at $count in $prods return if ($count = $numProds) then concat($prod/name,".") else concat($prod/name,",") }</p>
<p>{ let $prods := doc("catalog.xml")//product for $prod in $prods return if ($prod is $prods[last()]) then concat($prod/name,".") else concat($prod/name,", ") }</p>
let $cat := doc("catalog.xml")/catalog for $dept in distinct-values($cat/product/@dept) return <li>Department: {if ($dept = "ACC") then "Accessories" else if ($dept = "MEN") then "Menswear" else if ($dept = "WMN") then "Womens" else () } ({$dept})</li>
let $deptNames := <deptNames> <dept code="ACC" name="Accessories"/> <dept code="MEN" name="Menswear"/> <dept code="WMN" name="Womens"/> </deptNames> let $cat := doc("catalog.xml")/catalog for $dept in distinct-values($cat/product/@dept) return <li>Department: {data($deptNames/dept[@code = $dept]/@name) } ({$dept})</li>
let $tempResults:= for $item in doc("order.xml")//item, $product in doc("catalog.xml")//product where $item/@num = $product/number return <item num="{$item/@num}" name="{$product/name}" color="{$item/@color}" quant="{$item/@quantity}"/> return <table> <tr> <th>#</th><th>Name</th><th>Color</th><th>Quan</th> </tr> {for $lineItem in $tempResults return <tr> <td>{data($lineItem/@num)}</td> <td>{data($lineItem/@name)}</td> <td>{data($lineItem/@color)}</td> <td>{data($lineItem/@quant)}</td> </tr> } </table>