Last active
December 27, 2015 21:09
-
-
Save joewiz/f7044a582eab18cc26e0 to your computer and use it in GitHub Desktop.
EXPath Facet Spec workbook
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
xquery version "3.0"; | |
(:~ An implementation of facet:count as described in "Case 1: Simple facet based on existing attribute" | |
of the EXPath Facet Spec. Depends on eXist's util:eval() function to handle dynamic path expressions. | |
@see http://expath.org/spec/facet/20151225#case-1-simple-facet-based-on-existing-attribute | |
:) | |
import module namespace util="http://exist-db.org/xquery/util"; | |
declare namespace facet = "http://expath.org/ns/facet"; | |
declare function facet:count($results as item()*, $facet-definitions as element(facet:facet-definition)*) as element(facet:facets) { | |
<facet:facets> | |
<facet:facet name="{$facet-definitions/@name}"> | |
{ | |
for $r in $results | |
let $group-by-expression := concat('$r/', $facet-definitions/facet:group-by/facet:sub-path) | |
(: use util:eval() for dynamic evaluation of arbitrary paths in eXist :) | |
group by $g := util:eval($group-by-expression) | |
order by count($r) descending | |
return | |
<facet:key value="{ $g }" count="{ count($r) }"/> | |
} | |
</facet:facet> | |
</facet:facets> | |
}; | |
let $sample := | |
<sample> | |
<employee> | |
<name>John Doe</name> | |
<sex>Male</sex> | |
<organization>HR</organization> | |
<location> | |
<country>US</country> | |
<state>CA</state> | |
<city>Pleasanton</city> | |
<gps> | |
<longitude>-95.677068</longitude> | |
<latitude>37.0625</latitude> | |
</gps> | |
</location> | |
<age>21</age> | |
<employDate>2010-02-01</employDate> | |
<skills> | |
<skill>Word</skill> | |
<skill>Excel</skill> | |
<skill>Windows</skill> | |
</skills> | |
</employee> | |
<employee> | |
<name>Jane Joe</name> | |
<sex>Female</sex> | |
<organization>Finance</organization> | |
<location> | |
<country>US</country> | |
<state>CA</state> | |
<city>San Francisco</city> | |
<gps> | |
<longitude>-122.419416</longitude> | |
<latitude>37.77493</latitude> | |
</gps> | |
</location> | |
<age>18</age> | |
<employDate>2003-02-01</employDate> | |
<skills> | |
<skill>Word</skill> | |
<skill>Excel</skill> | |
<skill>PowerPoint</skill> | |
<skill>Linux</skill> | |
</skills> | |
</employee> | |
<employee> | |
<name>Steve</name> | |
<sex>Male</sex> | |
<organization>HR</organization> | |
<location> | |
<country>US</country> | |
<state>WA</state> | |
<city>Seattle</city> | |
<gps> | |
<longitude>-122.332071</longitude> | |
<latitude>47.60621</latitude> | |
</gps> | |
</location> | |
<age>31</age> | |
<employDate>2010-04-01</employDate> | |
<skills> | |
<skill>OpenOffice</skill> | |
<skill>Word</skill> | |
</skills> | |
</employee> | |
<employee> | |
<name>Kylie</name> | |
<sex>Female</sex> | |
<organization>Sales</organization> | |
<location> | |
<country>US</country> | |
<state>WA</state> | |
<city>Bellingham</city> | |
<gps> | |
<longitude>-122.488225</longitude> | |
<latitude>48.759553</latitude> | |
</gps> | |
</location> | |
<age>23</age> | |
<employDate>2010-06-01</employDate> | |
<skills> | |
<skill>Word</skill> | |
<skill>PowerPoint</skill> | |
</skills> | |
</employee> | |
<employee> | |
<name>Kyle</name> | |
<sex>Male</sex> | |
<organization>Sales</organization> | |
<location> | |
<country>US</country> | |
<state>WA</state> | |
<city>Bellingham</city> | |
<gps> | |
<longitude>-122.499225</longitude> | |
<latitude>48.759553</latitude> | |
</gps> | |
</location> | |
<age>45</age> | |
<employDate>2009-06-01</employDate> | |
<skills> | |
<skill>PowerPoint</skill> | |
<skill>PhotoShop</skill> | |
</skills> | |
</employee> | |
<employee> | |
<name>Mike</name> | |
<sex>Male</sex> | |
<organization>Sales</organization> | |
<location> | |
<country>US</country> | |
<state>OR</state> | |
<city>Eugene</city> | |
<gps> | |
<longitude>-123.086754</longitude> | |
<latitude>44.052069</latitude> | |
</gps> | |
</location> | |
<age>55</age> | |
<employDate>1999-06-01</employDate> | |
<skills> | |
<skill>PowerPoint</skill> | |
<skill>Negotiation</skill> | |
</skills> | |
</employee> | |
</sample> | |
let $employees := $sample/employee | |
let $facetDefinition := | |
<facet:facet-definition name="Org"> | |
<facet:group-by> | |
<facet:sub-path>organization</facet:sub-path> | |
</facet:group-by> | |
</facet:facet-definition> | |
return | |
facet:count($employees, $facetDefinition) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<facet:facets xmlns:facet="http://expath.org/ns/facet"> | |
<facet:facet name="Org"> | |
<facet:key value="Sales" count="3"/> | |
<facet:key value="HR" count="2"/> | |
<facet:key value="Finance" count="1"/> | |
</facet:facet> | |
</facet:facets> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
xquery version "3.0"; | |
(:~ An implementation of facet:count as described in "Case 2: Simple customized facet based on group-by function" | |
of the EXPath Facet Spec. Depends on eXist's util:eval() function to handle dynamic path expressions. | |
@see http://expath.org/spec/facet/20151225#case-2-simple-customized-facet-based-on-group-by-function | |
:) | |
import module namespace util="http://exist-db.org/xquery/util"; | |
declare namespace facet = "http://expath.org/ns/facet"; | |
declare function facet:count($results as item()*, $facet-definitions as element(facet:facet-definition)*) as element(facet:facets) { | |
<facet:facets> | |
<facet:facet name="{$facet-definitions/@name}"> | |
{ | |
for $r in $results | |
let $group-by-expression := | |
if ($facet-definitions/facet:group-by/@function) then | |
concat($facet-definitions/facet:group-by/@function, '($r/', $facet-definitions/facet:group-by/facet:sub-path, ')') | |
else | |
concat('$r/', $facet-definitions/facet:group-by/facet:sub-path) | |
(: use util:eval() for dynamic evaluation of arbitrary paths in eXist :) | |
group by $g := util:eval($group-by-expression) | |
order by count($r) descending | |
return | |
<facet:key value="{ $g }" count="{ count($r) }"/> | |
} | |
</facet:facet> | |
</facet:facets> | |
}; | |
declare function local:group-by-org($org as xs:string) { | |
if ($org = ('Sales', 'Finance')) then | |
'Sales and Finance' | |
else | |
'Other departments' | |
}; | |
let $sample := | |
<sample> | |
<employee> | |
<name>John Doe</name> | |
<sex>Male</sex> | |
<organization>HR</organization> | |
<location> | |
<country>US</country> | |
<state>CA</state> | |
<city>Pleasanton</city> | |
<gps> | |
<longitude>-95.677068</longitude> | |
<latitude>37.0625</latitude> | |
</gps> | |
</location> | |
<age>21</age> | |
<employDate>2010-02-01</employDate> | |
<skills> | |
<skill>Word</skill> | |
<skill>Excel</skill> | |
<skill>Windows</skill> | |
</skills> | |
</employee> | |
<employee> | |
<name>Jane Joe</name> | |
<sex>Female</sex> | |
<organization>Finance</organization> | |
<location> | |
<country>US</country> | |
<state>CA</state> | |
<city>San Francisco</city> | |
<gps> | |
<longitude>-122.419416</longitude> | |
<latitude>37.77493</latitude> | |
</gps> | |
</location> | |
<age>18</age> | |
<employDate>2003-02-01</employDate> | |
<skills> | |
<skill>Word</skill> | |
<skill>Excel</skill> | |
<skill>PowerPoint</skill> | |
<skill>Linux</skill> | |
</skills> | |
</employee> | |
<employee> | |
<name>Steve</name> | |
<sex>Male</sex> | |
<organization>HR</organization> | |
<location> | |
<country>US</country> | |
<state>WA</state> | |
<city>Seattle</city> | |
<gps> | |
<longitude>-122.332071</longitude> | |
<latitude>47.60621</latitude> | |
</gps> | |
</location> | |
<age>31</age> | |
<employDate>2010-04-01</employDate> | |
<skills> | |
<skill>OpenOffice</skill> | |
<skill>Word</skill> | |
</skills> | |
</employee> | |
<employee> | |
<name>Kylie</name> | |
<sex>Female</sex> | |
<organization>Sales</organization> | |
<location> | |
<country>US</country> | |
<state>WA</state> | |
<city>Bellingham</city> | |
<gps> | |
<longitude>-122.488225</longitude> | |
<latitude>48.759553</latitude> | |
</gps> | |
</location> | |
<age>23</age> | |
<employDate>2010-06-01</employDate> | |
<skills> | |
<skill>Word</skill> | |
<skill>PowerPoint</skill> | |
</skills> | |
</employee> | |
<employee> | |
<name>Kyle</name> | |
<sex>Male</sex> | |
<organization>Sales</organization> | |
<location> | |
<country>US</country> | |
<state>WA</state> | |
<city>Bellingham</city> | |
<gps> | |
<longitude>-122.499225</longitude> | |
<latitude>48.759553</latitude> | |
</gps> | |
</location> | |
<age>45</age> | |
<employDate>2009-06-01</employDate> | |
<skills> | |
<skill>PowerPoint</skill> | |
<skill>PhotoShop</skill> | |
</skills> | |
</employee> | |
<employee> | |
<name>Mike</name> | |
<sex>Male</sex> | |
<organization>Sales</organization> | |
<location> | |
<country>US</country> | |
<state>OR</state> | |
<city>Eugene</city> | |
<gps> | |
<longitude>-123.086754</longitude> | |
<latitude>44.052069</latitude> | |
</gps> | |
</location> | |
<age>55</age> | |
<employDate>1999-06-01</employDate> | |
<skills> | |
<skill>PowerPoint</skill> | |
<skill>Negotiation</skill> | |
</skills> | |
</employee> | |
</sample> | |
let $employees := $sample/employee | |
let $facetDefinition := | |
<facet:facet-definition name="Org"> | |
<facet:group-by function="local:group-by-org"> | |
<facet:sub-path>organization</facet:sub-path> | |
</facet:group-by> | |
</facet:facet-definition> | |
return | |
facet:count($employees, $facetDefinition) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<facet:facets xmlns:facet="http://expath.org/ns/facet"> | |
<facet:facet name="Org"> | |
<facet:key value="Sales and Finance" count="4"/> | |
<facet:key value="Other departments" count="2"/> | |
</facet:facet> | |
</facet:facets> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
xquery version "3.0"; | |
(:~ An implementation of facet:count as described in "Case 3: Counting facets when the grouping key consists of more than 1 value" | |
of the EXPath Facet Spec. Depends on eXist's util:eval() function to handle dynamic path expressions. | |
Fails with err:XPTY0004, as predicted by the spec: "There is no equivalent XQuery using group-by-clause, because skill is | |
a repeatable element. Following XQuery will throw err:XPTY0004." | |
@see http://expath.org/spec/facet/20151225#case-3-counting-facets-when-the-grouping-key-consists-of-more-than-1-value | |
:) | |
import module namespace util="http://exist-db.org/xquery/util"; | |
declare namespace facet = "http://expath.org/ns/facet"; | |
declare function facet:count($results as item()*, $facet-definitions as element(facet:facet-definition)*) as element(facet:facets) { | |
<facet:facets> | |
<facet:facet name="{$facet-definitions/@name}"> | |
{ | |
for $r in $results | |
let $group-by-expression := concat('$r/', $facet-definitions/facet:group-by/facet:sub-path) | |
(: use util:eval() for dynamic evaluation of arbitrary paths in eXist :) | |
group by $g := util:eval($group-by-expression) | |
order by count($r) descending | |
return | |
<facet:key value="{ $g }" count="{ count($r) }"/> | |
} | |
</facet:facet> | |
</facet:facets> | |
}; | |
let $sample := | |
<sample> | |
<employee> | |
<name>John Doe</name> | |
<sex>Male</sex> | |
<organization>HR</organization> | |
<location> | |
<country>US</country> | |
<state>CA</state> | |
<city>Pleasanton</city> | |
<gps> | |
<longitude>-95.677068</longitude> | |
<latitude>37.0625</latitude> | |
</gps> | |
</location> | |
<age>21</age> | |
<employDate>2010-02-01</employDate> | |
<skills> | |
<skill>Word</skill> | |
<skill>Excel</skill> | |
<skill>Windows</skill> | |
</skills> | |
</employee> | |
<employee> | |
<name>Jane Joe</name> | |
<sex>Female</sex> | |
<organization>Finance</organization> | |
<location> | |
<country>US</country> | |
<state>CA</state> | |
<city>San Francisco</city> | |
<gps> | |
<longitude>-122.419416</longitude> | |
<latitude>37.77493</latitude> | |
</gps> | |
</location> | |
<age>18</age> | |
<employDate>2003-02-01</employDate> | |
<skills> | |
<skill>Word</skill> | |
<skill>Excel</skill> | |
<skill>PowerPoint</skill> | |
<skill>Linux</skill> | |
</skills> | |
</employee> | |
<employee> | |
<name>Steve</name> | |
<sex>Male</sex> | |
<organization>HR</organization> | |
<location> | |
<country>US</country> | |
<state>WA</state> | |
<city>Seattle</city> | |
<gps> | |
<longitude>-122.332071</longitude> | |
<latitude>47.60621</latitude> | |
</gps> | |
</location> | |
<age>31</age> | |
<employDate>2010-04-01</employDate> | |
<skills> | |
<skill>OpenOffice</skill> | |
<skill>Word</skill> | |
</skills> | |
</employee> | |
<employee> | |
<name>Kylie</name> | |
<sex>Female</sex> | |
<organization>Sales</organization> | |
<location> | |
<country>US</country> | |
<state>WA</state> | |
<city>Bellingham</city> | |
<gps> | |
<longitude>-122.488225</longitude> | |
<latitude>48.759553</latitude> | |
</gps> | |
</location> | |
<age>23</age> | |
<employDate>2010-06-01</employDate> | |
<skills> | |
<skill>Word</skill> | |
<skill>PowerPoint</skill> | |
</skills> | |
</employee> | |
<employee> | |
<name>Kyle</name> | |
<sex>Male</sex> | |
<organization>Sales</organization> | |
<location> | |
<country>US</country> | |
<state>WA</state> | |
<city>Bellingham</city> | |
<gps> | |
<longitude>-122.499225</longitude> | |
<latitude>48.759553</latitude> | |
</gps> | |
</location> | |
<age>45</age> | |
<employDate>2009-06-01</employDate> | |
<skills> | |
<skill>PowerPoint</skill> | |
<skill>PhotoShop</skill> | |
</skills> | |
</employee> | |
<employee> | |
<name>Mike</name> | |
<sex>Male</sex> | |
<organization>Sales</organization> | |
<location> | |
<country>US</country> | |
<state>OR</state> | |
<city>Eugene</city> | |
<gps> | |
<longitude>-123.086754</longitude> | |
<latitude>44.052069</latitude> | |
</gps> | |
</location> | |
<age>55</age> | |
<employDate>1999-06-01</employDate> | |
<skills> | |
<skill>PowerPoint</skill> | |
<skill>Negotiation</skill> | |
</skills> | |
</employee> | |
</sample> | |
let $employees := $sample/employee | |
let $facetDefinition := | |
<facet:facet-definition name="Skill"> | |
<facet:group-by> | |
<facet:sub-path>skills/skill</facet:sub-path> | |
</facet:group-by> | |
</facet:facet-definition> | |
return | |
facet:count($employees, $facetDefinition) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<exception> | |
<path>/db/apps/facet/case-3.xq</path> | |
<message> | |
err:XPTY0004 Grouping variable g evaluates to more than one item [at line 164, column 5, source: /db/apps/facet/case-3.xq] | |
In function: facet:count(item()*, element()*) [164:5:/db/apps/facet/case-3.xq] | |
</message> | |
</exception> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment