% Must be run with prova_qizx[.bat] or, otherwise, with the latest qizxopen.jar with XQuery present on CLASSPATH.
% Example XML file books.xml should be available locally.
% Note that the output from this script is quite large (almost 1MB).
% Note also that the temporal XML files invoices.xml and clients.xml generated in test 3 are even larger (almost 3MB).
%     The second clause ex025() cleans them up at the end of the run.
% This example shows
%    - how to use XQuery under qizxopen,
%    - how beginning with Prova 1.8, one can use multi-line constant literals. Note that newline(s) are part of the string.

:- eval(ex025()).

ex025() :-
	Processor = net.xfra.qizxopen.xquery.XQueryProcessor(".","."),
	Log = net.xfra.qizxopen.xquery.Log(), % Writes on System.err by default
	Serial = net.xfra.qizxopen.dm.XMLSerializer(),
	on_exception(java.lang.Exception,catch_xquery_exception()),
	N = 0,
	assert(num(N)),
	query(S),
	num(N1),
	N2 = N1 + 1,
	retractall(num(_)),
	assert(num(N2)),
	run(N2,S,Processor,Log,Serial).
ex025() :-
	% Clean up
	F1=java.io.File("clients.xml"),
	F1.delete(),
	F2=java.io.File("invoices.xml"),
	F2.delete().

run(TestNo,S,Processor,Log,Serial) :-
	Writer = java.io.StringWriter(),
	Serial.setOutput(Writer),
	Q = Processor.compileQuery(S, "<source>", Log),
	println(["Test ",TestNo,": ",S]),
	println(["----------------------------"]),
	Processor.executeQuery( Q, Serial ),
	print([Writer]),
	println(["============================"]).

%query(' 
%<Q1>
%  {
%    for $n in distinct-values(
%	              for $i in (doc("auction.xml")/AuctionWatchList)
%                 return $i 
%               )
%    return  <ns>{$n}</ns>
%  }
%</Q1>').
%                  for $i in (doc("auction.xml")//* | doc("auction.xml")//@*)
%declare namespace dt = "xmlns";

%<Q3>
%  {
%    doc("Geocoding_ws.wsdl")//@*
%  }
%</Q3> 
query(' 

<Q_SECSE_01>
{
   for $a in doc("Description.xml")//Functionality
	[contains(string(.),"art-of-speech") or contains(string(.),"tagging")]
	return $a
}  
</Q_SECSE_01>
').
query(' 

<Q1>
  {

    for $n in distinct-values(
                  for $i in ( doc("Geocoding_ws.wsdl")//*:schema[2] )
                  return in-scope-prefixes($i)
               )
    return  <ns>{$n}</ns>
  }
</Q1>
').
query(' for $i in 1 to 3 return element E { attribute A { $i } } ').
query(' doc("books.xml") ').
query('
	for $x in doc("books.xml")/bib/book
		where $x/price>50
		order by $x/title
		return $x/title').
query('
	every $x in doc("books.xml")/bib/book/price
		satisfies $x>10').
query('
	for $b in doc("books.xml")//book
		where some $a in $b/author
			satisfies ($a/last="Stevens" and $a/first="W.")
		return $b/title').
query('
	for $b in doc("books.xml")//book
		where every $a in $b/author
			satisfies ($a/last="Stevens" and $a/first="W.")
		return $b/title').
query('
	for $b in doc("books.xml")//book
		return
			<book>
				{ $b/title }
				{
					for $a at $i in $b/author
					where $i <= 2
					return <author>{string($a/last),", ",string($a/first)}</author>
				}
				{
					if (count($b/author) > 2)
						then <author>et al.</author>
					else ()
				}
			</book>').
query('
<results>
{
   for $b in doc("books.xml")/bib/book
   return
        <result>
            { $b/title }
            { $b/author  }
        </result>
	}
</results>').
query('
<results>
  {
    let $a := doc("books.xml")//author
    for $last in distinct-values($a/last),
        $first in distinct-values($a[last=$last]/first)
    order by $last, $first
    return
        <result>
            <author>
               <last>{ $last }</last>
               <first>{ $first }</first>
            </author>
            {
                for $b in doc("books.xml")/bib/book
                where some $ba in $b/author 
                      satisfies ($ba/last = $last and $ba/first=$first)
                return $b/title
            }
        </result>
  }
</results>').
query('
	let $dict := 
	<entry word="address">    
		<variant lang="German">Adresse</variant>    
		<variant lang="Italian">indirizzo</variant>
	</entry> ,
	$e := <address>123 Roosevelt Ave. Flushing, NY 11368</address>
	return element { string($dict/variant[@lang="Italian"]/text()) } {$e/node() }').
query('
	declare variable $CCnt { 10000 };
	declare variable $ICnt { 30000 };

	x:serialize(
  		<clients>{ for $c in 1 to $CCnt 
             return <client><id>id{$c}</id>description of client {$c}</client> }</clients>,
  		<options output="clients.xml" indent="no"/>
	),
	x:serialize(
  		<invoices>{ for $i in 1 to $ICnt 
             return <invoice client-id="id{1 + $i mod $CCnt}">invoice {$i}
                      <amount>{100 + $i * 100 div $ICnt}</amount></invoice> }</invoices>,
  		<options output="invoices.xml" indent="no"/>
	)').
ooo_query('
	<report>
	<table>{
	(
		let $INVOICES := doc("invoices.xml")
		for $client in doc("clients.xml")//client
		let $cinv := (for $inv in $INVOICES//invoice
                 where ($inv/@client-id = $client/id)
     	           return $inv)
 		return <tr>
    	<td>{ text { $client/id }}</td>
    	<td>{ count($cinv) }</td>
    	<td>{ sum($cinv/amount) }</td>
  		</tr>
	)
	}</table>
	</report>
').

catch_xquery_exception() :-
	exception(Ex),
	println([Ex]).