############################################################################################## Implementation of TMQL use cases with TMPath-TMQuery Use cases sources: http://www.y12.doe.gov/sgml/sc34/document/0449.htm http://www.isotopicmaps.org/tmql/use-cases.html Based on TMPath Revisited: http://homepage.mac.com/dmitryv/TopicMaps/TMPath/TMPathRevisited.html Copyright @ 2003 Dmitry Bogachev ############################################################################################## 1. Retrieve all author names, i.e. the name of a topic which plays the role author in an is-author-of association: "Holger Rath" "Michel Biezunski" "Steve Pepper" "Steve Newcomb" list{ for $Author in /topic[*;roleOf::author[is-author-of]/role::opus] return $Author/bn::*[1] } 2.Retrieve the name of all authors, this time ordered by the sort name provided in person topics: "Michel Biezunski" "Holger Rath" "Steve Newcomb" "Steve Pepper" list{ for $Author in /topic[*;roleOf::author[is-author-of]/role::opus] order by $Author/bn::*@sort[1] return $Author/bn::*[1] } 3. Retrieve the titles of all tutorials. The titles should be preferably those in scope en, de or in the unconstrained scope, in that order. "Making topic maps more colourful" "Euler, Topic Maps und Revolution" list{ for $Tutorial in /topic[tutorial] return ( $Tutorial/bn::*@en[1], $Tutorial/bn::*@de[1], $Tutorial/bn::*[1]) } 4. Retrieve the names of all persons who have not authored anything. "John Smith" list{ for $Person in /topic[person;not(roleOf::author[is-author-of]/role::opus)] return $Person/bn::*[1] } 5. Retrieve a list of all author names together with the title of their publications. "Holger Rath", "Making topic maps more colourful" "Steve Pepper", "Euler, topic maps, and revolution" "Steve Pepper", "Navigating haystacks and discovering needles" "Steve Pepper", "The TAO of Topic Maps" "Steve Newcomb", "XML topic maps: finding aids for the Web" "Michel Biezunski", "XML topic maps: finding aids for the Web" list{ for $Author in /topic[*;roleOf::author[is-author-of]/role::opus] for $Pub in $Author/roleOf::author[is-author-of]/role::opus return list{$Author/bn::*[1],$Pub/bn::*[1]} } Note: TMQuery allows using of binary projections for associations. This query can be rewritten with binary projections as following: define step authorOfOpus() { $$self/roleOf::author@$$scope[is-author-of]/role::opus } list{ for $Author in /topic[*;authorOfOpus] for $Pub in $Author/authorOfOpus return list{$Author/bn::*[1],$Pub/bn::*[1]} } Note: To simplify choosing one of the values TMQuery allows ! prefix operator For example, it is possible to use !$Pub/bn instead of $Pub/bn[1]. Last example can be rewritten as following: list{ for $Author in /topic[*;authorOfOpus] for $Pub in $Author/authorOfOpus return list{!$Author/bn::*,!$Pub/bn::*} } 6. Retrieve a list of all titles of documents which are tutorials (i.e. are a direct or indirect instance of class tutorial) sorted by publication date, descending "Making topic maps more colourful", 2000 "Euler, topic maps, and revolution", 1999 list{ for $Pub in /topic[tutorial] order by !$Pub/oc::publication-date descending return list{!$Pub/bn::*,!$Pub/oc::publication-date} } 7. Retrieve a list of documents, sorted by publication date (ascending), only number 3 to 5, inclusive, together with this order number 3,"The TAO of Topic Maps", 2000 4,"Making topic maps more colourful", 2000 5,"XML topic maps: finding aids for the Web", 2001 list{ for $Pub at $i in /topic[*;roleOf::opus[is-author-of]/role::author] order by !$Pub/oc::publication-date ascending offset 3 limit 3 return list{$i, !$Pub/bn::*, !$Pub/oc::publication-date} } 8. Retrieve all topic identifiers of documents which have a download URL. pepper99a pepp00 d-topicmaps-color list{ for $Doc in /topic[*;roleOf::opus[is-author-of]/role::author and oc::download] return !$Doc/id } 9. Retrieve a list of author's email addresses where the author has authored documents for which no download URL exists. Include the topic identifiers of these documents. pepper@n0spam.ontopia.net, pepper99b srn@n0spam.coolheads.com, bienew01 mb@n0spam.coolheads.com, bienew01 list{ for $Author in /topic[*;roleOf::author[is-author-of]/role::opus[*;not(oc::download)]] for $Pub in $Author/roleOf::author[is-author-of]/role::opus[*;not(oc::download)] return list{!$Author/oc::email,!$Pub/id} } 10. Retrieve a list of author names where the author has written more than 1 document. "Steve Pepper" list{ for $Author in /topic[*;count(roleOf::author[is-author-of]/role::opus)>1] return !$Author/bn::* } 11. A list of author names where the author has not written a single document with someone else. "Steve Pepper" "Holger Rath" list{ for $Author in /topic[*;roleOf::author[is-author-of]/role::opus] let $Pubs := $Author/roleOf::author[is-author-of]/role::opus where every $Pub in $Pubs satisfies not($Pub/roleOf::opus[is-author-of]/role::author!=$Author) return !$Author/bn::* } With binary projections: list{ for $Author in /topic[*;author-of] let $Pubs := $Author/author-of where every $Pub in $Pubs satisfies not($Pub/has-author!=$Author) return !$Author/bn::* } 12. Retrieve all topic identifiers of documents and their URLs which have a non-working URL at query time. pepp00, http://www.broken.example.com/ list{ for $Doc in /topic[*;roleOf::opus[is-author-of]/role::author and oc::download] where not(isWorkingURI($Doc/oc::download)) return list{!$Doc/id,!$Doc/oc::download} } 13. Retrieve all topic identifiers for documents for which the abstract in english (i.e. the occurrence of type abstract in scope en) contains the phrase 'topic map' or 'topic maps', case-insensitive. pepp00 bienew01 list{ for $Doc in /topic[*;roleOf::opus[is-author-of]/role::author] where contains($Doc/oc::abstract@en,("topic map","topic maps")) return !$Doc/id } 14. Retrieve all documents which have a title in german (i.e. a basename in the scope de). [ empty list ] list{ for $Doc in /topic[*;roleOf::opus[is-author-of]/role::author] where $Doc/bn::*@de return !$Doc/id } 15. Retrieve all topic identifiers of the pairs of documents which share at least one word in the title, ignoring stopwords like 'and', 'of', 'the'. No duplicates in this list are allowed. pepper99a, pepp00 pepper99a, d-topicmaps-color pepper99a, bienew01 pepp00, d-topicmaps-color pepp00, bienew01 d-topicmaps-color, bienew01 list{ let $StopList:=("and","of","the") for $Doc1 in /topic[*;roleOf::opus[is-author-of]/role::author] for $Doc2 in /topic[*;roleOf::opus[is-author-of]/role::author] let $WordList1:=split(!$Doc1::bn:*) except $StopList let $WordList2:=split(!$Doc2::bn:*) except $StopList where not(empty($WordList1 intersect $WordList2)) return list {!$Doc1/id,!$Doc2/id} } 16. Retrieve the identifiers of all topics which represent information resources on the ontopia.net server(s). pepper99a pepp00 list{ for $Doc1 in /topic[*;match(subl,".*ontopia\.net.*")] return !$Doc1/id } 17. Retrieve the topic identifiers of all documents which are not written in the language English (or where there is no information about that), i.e. where there is no occurrence of type language. pepper99b pepp00 d-topicmaps-color list{ for $Doc1 in /topic[*,roleOf::opus[is-author-of]/role::author and not(oc::language="English")] return !$Doc1/id } 18. Retrieve the topic identifiers of all documents which are directly or indirectly influenced by something which Steve Pepper wrote (i.e. interpreting "influenced by" as non-reflexive, but transitive relation). Copy the topic identifiers of the influential papers to the output. pepper99b, 'influenced by', pepper99a d-topicmaps-color, 'influenced by', pepper99b d-topicmaps-color, 'influenced by', pepper99a bienew01, 'influenced by', pepper99b bienew01, 'influenced by', pepper99a [transitive=true] define step has-influence-on() { $$self/roleOf::target@$$scope[influenced-by]/role::source } define step authored-by() { $$self/roleOf::opus@$$scope[is-author-of]/role::author } list{ for $Doc1 in /topic[*; authored-by=pepper] let $Docs:=$Doc1//has-influence-on for $Doc2 in $Docs where not(empty($Docs)) order by !$Doc2/id return list{!$Doc2/id,'influenced by',!$Doc1/id} } 19. Retrieve all identifiers of topics which are either (direct or indirect) instances of paper or tutorial. Duplicates should be suppressed. pepper99a pepper99b d-topicmaps-color bienew01 list{ for $Doc in /topic[paper|tutorial] return !$Doc/id } 20. Retrieve all titles of all publications (regardless their scope) together with their most specific class, i.e. that class where this publication is directly (and not indirectly) an instance of. Euler, topic maps, and revolution, conference-paper Euler, topic maps, and revolution, tutorial Euler, Topic Maps und Revolution, conference-paper Euler, Topic Maps und Revolution, tutorial Navigating haystacks and discovering needles, journal-paper The TAO of Topic Maps, article Making topic maps more colourful, tutorial XML topic maps: finding aids for the Web, journal-paper list{ for $Doc in /topic[document] return List{!$Doc/bn::*,!$Doc/type} } 21. Retrieve all authors (i.e. all topic items which play the role author in an is-author-of association). [ holger-rath ] [ michel-biezunski ] [ steve-pepper ] [ steve-newcomb ] for $Author in /topic[*;roleOf::author[is-author-of]/role::opus] return topic($Author){} 22. Retrieve all basename items of topics which play the role author in an is-author-of association). [ "Holger Rath", unconstrained-scope ] [ "Michel Biezunski", unconstrained-scope ] [ "Steve Pepper", unconstrained-scope ] [ "Steve Newcomb", unconstrained-scope ] for $BaseName in /topic[*;roleOf::author[is-author-of]/role::opus]/bn return baseName($BaseName){} 23. Retrieve a list of all occurrence items being of type email. [ email, srn@n0spam.coolheads.com, unconstrained-scope ] [ email, mb@n0spam.coolheads.com, unconstrained-scope ] [ email, pepper@n0spam.ontopia.net, unconstrained-scope ] [ email, holger.rath@n0spam.empolis.com, unconstrained-scope ] [ email, j.smith@example.com, unconstrained-scope ] for $Occurrence in /topic[*]/oc[email] return occurrence($Occurrence){} 53.1 Return all titles which are from papers (conference, journals) together with the authors. No order is prescribed. The result has to follow the DTD (white spaces can, of course, be ignored in elements which contain only elements): { for $Doc in /topic[paper] return {!$Doc/bn::*} { for $Author in $Doc/roleOf::opus[is-author-of]/role::author return {!$Author/bn::*} } } 53.2 Return all authors with more than one papers according to the following DTD: { for $Author in /topic[*; count(roleOf::author[is-author-of]/role::opus[paper])>1] return {!$Author/bn::*} } 53.3 Select only the tutorial documents from the topic map and return an RDF document containing the title and the author information { for $Tutorial in /topic[tutorial], for $Author in $Tutorial/roleOf::opus[is-author-of]/role::author return {!$Tutorial/bn::*} {!$Author/bn::*} } 53.4 Return all persons with their name and a bibliography as nested elements { for $Person in /topic[person] let $Name:=$Person/bn::*@sort let $Pubs:=$Person/roleOf::author[is-author-of]/role::opus return {!$Name} { for $Pub in $Pubs return {!$Pub/bn::*} { if ($Pub/oc::language) then !$Pub/oc::language else "(unknown)" } } } 54.1 Select only journal papers and deliver them together with the relevant author associations as topic map (fragments [xtmfragments]). There is no need to include the author topics as well. Replace all occurrences of type publication-date with associations of type was-published-in. For the date-role the topic players should use ids of the form x-dates-yyyy. Note: this solution is very very preliminary topicMap{ for $journalPaper in /topic[journal-paper] for $IsAuthor in /a[is-author_of; role::opus=$journalPaper] return( topic($journalPaper){ oc[publication-date] replaceWith null } $IsAuthor association was-published-in{ role opus {$journalPaper} role date-role { topic{ id{concat("x-dates-",!$journalPaper/oc::publication-date)} } } } ) }