XQuery Code Walk-Through
The XQuery source is in examples/xmlpatterns/xquery/globalVariables/reportGlobals.xq It begins with two variable declarations that begin the XQuery:
declare variable $fileToOpen as xs:anyURI external;
declare variable $inDoc as document-node() := doc($fileToOpen);
The first variable, $fileToOpen, appears in the xmlpatterns command shown earlier, as -param fileToOpen=globals.gccxml. This binds the variable name to the file name. This variable is then used in the declaration of the second variable, $inDoc, as the parameter to the doc() function. The doc() function returns the document node of globals.gccxml, which is assigned to $inDoc to be used later in the XQuery as the root node of our searches for global variables.
Next skip to the end of the XQuery, where the <html> element is constructed. The <html> will contain a <head> element to specify a heading for the html page, followed by some style instructions for displaying the text, and then the <body> element.
<html xmlns="http://www.w3.org/1999/xhtml/" xml:lang="en" lang="en">
<head>
<title>Global variables report for {$fileToOpen}</title>
</head>
<style type="text/css">
.details
{{
text-align: left;
font-size: 80%;
color: blue
}}
.variableName
{{
font-family: courier;
color: blue
}}
</style>
<body>
<p class="details">Start report: {current-dateTime()}</p>
{
local:report()
}
<p class="details">End report: {current-dateTime()}</p>
</body>
</html>
The <body> element contains a call to the local:report() function, which is where the query does the "heavy lifting." Note the two return clauses separated by the comma operator about halfway down:
declare function local:report() as element()+
{
let $complexVariables as element(Variable)* := $inDoc/GCC_XML/Variable[local:isComplexType(@type)]
return if (exists($complexVariables))
then (<p xmlns="http://www.w3.org/1999/xhtml/">Global variables with complex types:</p>,
<ol xmlns="http://www.w3.org/1999/xhtml/">
{
(: For each Variable in $complexVariables... :)
$complexVariables/<li><span class="variableName">{string(@name)}</span> in {local:location(.)}</li>
}
</ol>)
else <p xmlns="http://www.w3.org/1999/xhtml/">No complex global variables found.</p>
,
let $primitiveVariables as element(Variable)+ := $inDoc/GCC_XML/Variable[local:isPrimitive(@type)]
return if (exists($primitiveVariables))
then (<p xmlns="http://www.w3.org/1999/xhtml/">Mutable global variables with primitives types:</p>,
<ol xmlns="http://www.w3.org/1999/xhtml/">
{
(: For each Variable in $complexVariables... :)
$primitiveVariables/<li><span class="variableName">{string(@name)}</span> in {local:location(.)}</li>
}
</ol>)
else <p xmlns="http://www.w3.org/1999/xhtml/">No mutable primitive global variables found.</p>
};
The return clauses are like two separate queries. The comma operator separating them means that both return clauses are executed and both return their results, or, rather, both output their results. The first return clause searches for global variables with complex types, and the second searches for mutable global variables with primitive types.
Here is the html generated for the <body> element. Compare it with the XQuery code above:
<body>
<p class="details">Start report: 2008-12-16T13:43:49.65Z</p>
<p>Global variables with complex types:</p>
<ol>
<li>
<span class="variableName">mutableComplex1</span> in globals.cpp at line 14</li>
<li>
<span class="variableName">mutableComplex2</span> in globals.cpp at line 15</li>
<li>
<span class="variableName">constComplex1</span> in globals.cpp at line 16</li>
<li>
<span class="variableName">constComplex2</span> in globals.cpp at line 17</li>
</ol>
<p>Mutable global variables with primitives types:</p>
<ol>
<li>
<span class="variableName">mutablePrimitive1</span> in globals.cpp at line 1</li>
<li>
<span class="variableName">mutablePrimitive2</span> in globals.cpp at line 2</li>
</ol>
<p class="details">End report: 2008-12-16T13:43:49.65Z</p>
</body>
The XQuery declares three more local functions that are called in turn by the local:report() function. isComplexType() returns true if the variable has a complex type. The variable can be mutable or const.
declare function local:isComplexType($typeID as xs:string) as xs:boolean
{
exists($inDoc/GCC_XML/Class[@id = $typeID])
or
exists($inDoc/GCC_XML/Class[@id = $inDoc/GCC_XML/CvQualifiedType[@id = $typeID]/@type])
};
isPrimitive() returns true if the variable has a primitive type. The variable must be mutable.
declare function local:isPrimitive($typeId as xs:string) as xs:boolean
{
exists($inDoc/GCC_XML/FundamentalType[@id = $typeId])
};
location() returns a text constructed from the variable's file and line number attributes.
declare function local:location($block as element()) as xs:string
{
concat($inDoc/GCC_XML/File[@id = $block/@file]/@name, " at line ", $block/@line)
};