xquery version "1.0"; (::pragma exist:serialize expand-xincludes=no indent=yes ::) declare namespace util="http://exist-db.org/xquery/util"; declare namespace i18n="http://apache.org/cocoon/i18n/2.1"; import module namespace ristenutil="http://www.risten.no/shared/util" at "../xquery/ristenutil.xqm"; (: Create filter expression from query term :) declare function local:filter-expr($term as xs:string) as xs:string { let $class := request:request-parameter("class", "") let $c := if ($class = 'all') then "" else if (contains($class, '-') ) then concat(".//@botm &= '", substring-after($class, '-'), "'" ) else if ( string-length($class) = 1) then concat(".//@top &= '", $class, "'" ) else concat(".//@mid &= '", $class, "'" ) let $f := ".//@href", (: Search the @href for the search term - it is in the ID of the referenced entry :) $t := concat("'", $term, "'") return if ($term = '*' or $term = '' ) then $c else if ( $class = 'all') then concat($f, " &= ", $t) else concat($f, " &= ", $t, " and ", $c) }; (: Map order parameter to xpath for order by clause :) (: Since the ordering element is not selectable (in the search form), this function does not make any sense any more, but I'll keep it for now just in case. :) declare function local:order-expr($field as xs:string) as xs:string { if ($field = "head") then "common/head" else "common/qa, $r/common/head" }; (: Assemble the query string :) declare function local:build-query($term as xs:string, $orderby as xs:string) as xs:string { let $expr := local:filter-expr($term), $t := request:set-session-attribute("query", $expr), $coll := ristenutil:get-collection(), $docs := concat($coll,"/termcenter.xml") return concat("for $r in document('", $docs, "')//entry[", $expr, "] return $r") }; (: Present an overview of query results :) declare function local:displayHitlist($hits as node()+) as element() { let $count := count($hits), $max := request:request-parameter("howmany", "10") cast as xs:int, $start := request:request-parameter("start", "1") cast as xs:int, $end := if ($start + $max - 1 < $count) then $start + $max - 1 else $count, $lang := request:request-parameter("showlang", "all") return { for $p in $start to $end let $current := item-at($hits, $p) return $current } }; (: Main function - retrieves some request and session attributes, forks further processing to other defined functions depending on the retrieved values :) declare function local:main() as element()+ { let $term := request:request-parameter("term", ""), $previous := request:get-session-attribute("results"), $queryOld := request:get-session-attribute("query"), $session := request:session-attributes(), $request := request:parameter-names(), $class := request:request-parameter("class", "") (: DEBUG ONLY: :) , $showlang := request:request-parameter("showlang",""), $testdocs := "/db/ordbase/terms/SD-terms/termcenter.xml" return if ( string-length($term) = 0 and string-length($class) = 0 ) then if (exists($previous)) then local:displayHitlist($previous) else

Your query has timed out, or was too unspecific. Please hit the «Find» button again, or enter a new search query.

else if ($term = "*" and $class = "all") then

Sorry, you cannot search for the whole db. Please enter a slightly more specific search - adding one character or specifying a topic is enough.

else let $query := local:build-query($term, "head"), $hits := util:eval( $query ), $s := request:set-session-attribute("results", $hits) return if (empty($hits)) then (

NoHit «{$term}» / «{$class}»!

,
) else ( (: DEBUG only - output some extra info :) (:

Your document string: {$testdocs}
Your $lang string: {$showlang}
Your session attributes: {$session}
Your request attributes: {$request}
Your class request: {$class}
Your old/short search query: {$queryOld}
Your complete search query:
{$query}

, :)

UrSrchTrm: «{$term}» / «{$class}»

,
, local:displayHitlist($hits) ) };
{ let $start := util:system-time() return ( local:main(),

SearchTime { seconds-from-duration(util:system-time()-$start) }

) }