If you want to run the examples yourself, they are included in the magic/xml package. Whitespace has been changed for easier reading. The original use cases are available on W3C website.
1 <?xml version="1.0" encoding="ISO-8859-1"?> 2 <partlist> 3 <part partid="0" name="car"/> 4 <part partid="1" partof="0" name="engine"/> 5 <part partid="2" partof="0" name="door"/> 6 <part partid="3" partof="1" name="piston"/> 7 <part partid="4" partof="2" name="window"/> 8 <part partid="5" partof="2" name="lock"/> 9 <part partid="10" name="skateboard"/> 10 <part partid="11" partof="10" name="board"/> 11 <part partid="12" partof="10" name="wheel"/> 12 <part partid="20" name="canoe"/> 13 </partlist>
Convert the sample document from "partlist" format to "parttree" format (see DTD section for definitions). In the result document, part containment is represented by containment of one <part> element inside another. Each part that is not part of any other part should appear as a separate top-level element in the output document.
1 def parts_of(parts, partid) 2 res = [] 3 parts.each{|p| 4 if p[:partof] == partid 5 a = p.attrs.dup 6 a.delete :partof 7 res << xml(:part, a, parts_of(parts, p[:partid])) 8 end 9 } 10 res 11 end 12 13 XML.parttree! { 14 parts = XML.load('partlist.xml').children(:part) 15 add! parts_of(parts, nil) 16 }
declare function local:one_level($p as element()) as element() { <part partid="{ $p/@partid }" name="{ $p/@name }" > { for $s in doc("partlist.xml")//part where $s/@partof = $p/@partid return local:one_level($s) } </part> }; <parttree> { for $p in doc("partlist.xml")//part[empty(@partof)] return local:one_level($p) } </parttree>
1 <parttree> 2 <part partid="0" name="car"> 3 <part partid="1" name="engine"> 4 <part partid="3" name="piston"/> 5 </part> 6 <part partid="2" name="door"> 7 <part partid="4" name="window"/> 8 <part partid="5" name="lock"/> 9 </part> 10 </part> 11 <part partid="10" name="skateboard"> 12 <part partid="11" name="board"/> 13 <part partid="12" name="wheel"/> 14 </part> 15 <part partid="20" name="canoe"/> 16 </parttree>
1 <bids> 2 <bid_tuple> 3 <userid>U02</userid> 4 <itemno>1001</itemno> 5 <bid>35</bid> 6 <bid_date>1999-01-07</bid_date></bid_tuple> 7 <bid_tuple> 8 <userid>U04</userid> 9 <itemno>1001</itemno> 10 <bid>40</bid> 11 <bid_date>1999-01-08</bid_date></bid_tuple> 12 <bid_tuple> 13 <userid>U02</userid> 14 <itemno>1001</itemno> 15 <bid>45</bid> 16 <bid_date>1999-01-11</bid_date></bid_tuple> 17 <bid_tuple> 18 <userid>U04</userid> 19 <itemno>1001</itemno> 20 <bid>50</bid> 21 <bid_date>1999-01-13</bid_date></bid_tuple> 22 <bid_tuple> 23 <userid>U02</userid> 24 <itemno>1001</itemno> 25 <bid>55</bid> 26 <bid_date>1999-01-15</bid_date></bid_tuple> 27 <bid_tuple> 28 <userid>U01</userid> 29 <itemno>1002</itemno> 30 <bid>400</bid> 31 <bid_date>1999-02-14</bid_date></bid_tuple> 32 <bid_tuple> 33 <userid>U02</userid> 34 <itemno>1002</itemno> 35 <bid>600</bid> 36 <bid_date>1999-02-16</bid_date></bid_tuple> 37 <bid_tuple> 38 <userid>U03</userid> 39 <itemno>1002</itemno> 40 <bid>800</bid> 41 <bid_date>1999-02-17</bid_date></bid_tuple> 42 <bid_tuple> 43 <userid>U04</userid> 44 <itemno>1002</itemno> 45 <bid>1000</bid> 46 <bid_date>1999-02-25</bid_date></bid_tuple> 47 <bid_tuple> 48 <userid>U02</userid> 49 <itemno>1002</itemno> 50 <bid>1200</bid> 51 <bid_date>1999-03-02</bid_date></bid_tuple> 52 <bid_tuple> 53 <userid>U04</userid> 54 <itemno>1003</itemno> 55 <bid>15</bid> 56 <bid_date>1999-01-22</bid_date></bid_tuple> 57 <bid_tuple> 58 <userid>U05</userid> 59 <itemno>1003</itemno> 60 <bid>20</bid> 61 <bid_date>1999-02-03</bid_date></bid_tuple> 62 <bid_tuple> 63 <userid>U01</userid> 64 <itemno>1004</itemno> 65 <bid>40</bid> 66 <bid_date>1999-03-05</bid_date></bid_tuple> 67 <bid_tuple> 68 <userid>U03</userid> 69 <itemno>1007</itemno> 70 <bid>175</bid> 71 <bid_date>1999-01-25</bid_date></bid_tuple> 72 <bid_tuple> 73 <userid>U05</userid> 74 <itemno>1007</itemno> 75 <bid>200</bid> 76 <bid_date>1999-02-08</bid_date></bid_tuple> 77 <bid_tuple> 78 <userid>U04</userid> 79 <itemno>1007</itemno> 80 <bid>225</bid> 81 <bid_date>1999-02-12</bid_date></bid_tuple></bids>
1 <items> 2 <item_tuple> 3 <itemno>1001</itemno> 4 <description>Red Bicycle</description> 5 <offered_by>U01</offered_by> 6 <start_day>1999-01-05</start_day> 7 <end_day>1999-01-20</end_day> 8 <reserve_price>40</reserve_price></item_tuple> 9 <item_tuple> 10 <itemno>1002</itemno> 11 <description>Motorcycle</description> 12 <offered_by>U02</offered_by> 13 <start_day>1999-02-11</start_day> 14 <end_day>1999-03-15</end_day> 15 <reserve_price>500</reserve_price></item_tuple> 16 <item_tuple> 17 <itemno>1003</itemno> 18 <description>Old Bicycle</description> 19 <offered_by>U02</offered_by> 20 <start_day>1999-01-10</start_day> 21 <end_day>1999-02-20</end_day> 22 <reserve_price>25</reserve_price></item_tuple> 23 <item_tuple> 24 <itemno>1004</itemno> 25 <description>Tricycle</description> 26 <offered_by>U01</offered_by> 27 <start_day>1999-02-25</start_day> 28 <end_day>1999-03-08</end_day> 29 <reserve_price>15</reserve_price></item_tuple> 30 <item_tuple> 31 <itemno>1005</itemno> 32 <description>Tennis Racket</description> 33 <offered_by>U03</offered_by> 34 <start_day>1999-03-19</start_day> 35 <end_day>1999-04-30</end_day> 36 <reserve_price>20</reserve_price></item_tuple> 37 <item_tuple> 38 <itemno>1006</itemno> 39 <description>Helicopter</description> 40 <offered_by>U03</offered_by> 41 <start_day>1999-05-05</start_day> 42 <end_day>1999-05-25</end_day> 43 <reserve_price>50000</reserve_price></item_tuple> 44 <item_tuple> 45 <itemno>1007</itemno> 46 <description>Racing Bicycle</description> 47 <offered_by>U04</offered_by> 48 <start_day>1999-01-20</start_day> 49 <end_day>1999-02-20</end_day> 50 <reserve_price>200</reserve_price></item_tuple> 51 <item_tuple> 52 <itemno>1008</itemno> 53 <description>Broken Bicycle</description> 54 <offered_by>U01</offered_by> 55 <start_day>1999-02-05</start_day> 56 <end_day>1999-03-06</end_day> 57 <reserve_price>25</reserve_price></item_tuple></items>
1 <users> 2 <user_tuple> 3 <userid>U01</userid> 4 <name>Tom Jones</name> 5 <rating>B</rating></user_tuple> 6 <user_tuple> 7 <userid>U02</userid> 8 <name>Mary Doe</name> 9 <rating>A</rating></user_tuple> 10 <user_tuple> 11 <userid>U03</userid> 12 <name>Dee Linquent</name> 13 <rating>D</rating></user_tuple> 14 <user_tuple> 15 <userid>U04</userid> 16 <name>Roger Smith</name> 17 <rating>C</rating></user_tuple> 18 <user_tuple> 19 <userid>U05</userid> 20 <name>Jack Sprat</name> 21 <rating>B</rating></user_tuple> 22 <user_tuple> 23 <userid>U06</userid> 24 <name>Rip Van Winkle</name> 25 <rating>B</rating></user_tuple></users>
List the item number and description of all bicycles that currently have an auction in progress, ordered by item number.
1 current_day = "1999-01-31" 2 3 items = XML.load('items.xml').sort_by{|i| i[:@itemno].to_i} 4 XML.result! { 5 items.each(XML) {|i| 6 next unless current_day.between?(i[:@start_day], i[:@end_day]) and i[:@description] =~ /Bicycle/ 7 item_tuple!(i.children(:itemno), i.children(:description)) 8 } 9 }
<result> { for $i in doc("items.xml")//item_tuple where $i/start_date <= current-date() and $i/end_date >= current-date() and contains($i/description, "Bicycle") order by $i/itemno return <item_tuple> { $i/itemno } { $i/description } </item_tuple> } </result>
1 <result> 2 <item_tuple> 3 <itemno>1003</itemno> 4 <description>Old Bicycle</description> 5 </item_tuple> 6 <item_tuple> 7 <itemno>1007</itemno> 8 <description>Racing Bicycle</description> 9 </item_tuple> 10 </result>
For all bicycles, list the item number, description, and highest bid (if any), ordered by item number.
1 items = XML.load('items.xml').sort_by{|i| i[:@itemno].to_i} 2 bids = XML.load('bids.xml') 3 4 XML.result! { 5 items.each({:@description => /Bicycle/}){|i| 6 item_tuple! { 7 add! i.children(:itemno) 8 add! i.children(:description) 9 10 item_bids = bids.find_all{|b| b.is_a? XML and b[:@itemno] == i[:@itemno] } 11 high_bid! item_bids.map{|b| b[:@bid].to_i}.max 12 } 13 } 14 }
<result> { for $i in doc("items.xml")//item_tuple let $b := doc("bids.xml")//bid_tuple[itemno = $i/itemno] where contains($i/description, "Bicycle") order by $i/itemno return <item_tuple> { $i/itemno } { $i/description } <high_bid>{ max($b/bid) }</high_bid> </item_tuple> } </result>
1 <result> 2 <item_tuple> 3 <itemno>1001</itemno> 4 <description>Red Bicycle</description> 5 <high_bid>55</high_bid> 6 </item_tuple> 7 <item_tuple> 8 <itemno>1003</itemno> 9 <description>Old Bicycle</description> 10 <high_bid>20</high_bid> 11 </item_tuple> 12 <item_tuple> 13 <itemno>1007</itemno> 14 <description>Racing Bicycle</description> 15 <high_bid>225</high_bid> 16 </item_tuple> 17 <item_tuple> 18 <itemno>1008</itemno> 19 <description>Broken Bicycle</description> 20 <high_bid></high_bid> 21 </item_tuple> 22 </result>
Find cases where a user with a rating worse (alphabetically, greater) than "C" is offering an item with a reserve price of more than 1000.
1 items = XML.load('items.xml') 2 users = XML.load('users.xml') 3 4 XML.result! { 5 users.each(XML){|u| 6 next unless u[:@rating] > "C" 7 items.each(XML){|i| 8 next unless i[:@reserve_price].to_i > 1000 9 warning!(u.child(:name), u.child(:rating), i.child(:description), i.child(:reserve_price)) 10 } 11 } 12 }
<result> { for $u in doc("users.xml")//user_tuple for $i in doc("items.xml")//item_tuple where $u/rating > "C" and $i/reserve_price > 1000 and $i/offered_by = $u/userid return <warning> { $u/name } { $u/rating } { $i/description } { $i/reserve_price } </warning> } </result>
1 <result> 2 <warning> 3 <name>Dee Linquent</name> 4 <rating>D</rating> 5 <description>Helicopter</description> 6 <reserve_price>50000</reserve_price> 7 </warning> 8 </result>
List item numbers and descriptions of items that have no bids. For bicycle(s) offered by Tom Jones that have received a bid, list the item number, description, highest bid, and name of the highest bidder, ordered by item number.
1 items = XML.load('items.xml') 2 bids = XML.load('bids.xml') 3 4 XML.result!{ 5 items.each(XML){|i| 6 next if bids.any?{|b| b.is_a? XML and b[:@itemno] == i[:@itemno]} 7 no_bid_item!(i.child(:itemno), i.child(:description)) 8 } 9 }
<result> { for $i in doc("items.xml")//item_tuple where empty(doc("bids.xml")//bid_tuple[itemno = $i/itemno]) return <no_bid_item> { $i/itemno } { $i/description } </no_bid_item> } </result>
1 <result> 2 <no_bid_item> 3 <itemno>1005</itemno> 4 <description>Tennis Racket</description> 5 </no_bid_item> 6 <no_bid_item> 7 <itemno>1006</itemno> 8 <description>Helicopter</description> 9 </no_bid_item> 10 <no_bid_item> 11 <itemno>1008</itemno> 12 <description>Broken Bicycle</description> 13 </no_bid_item> 14 </result>
1 items = XML.load('items.xml').sort_by{|i| i[:@itemno].to_i} 2 users = XML.load('users.xml') 3 bids = XML.load('bids.xml') 4 5 XML.result! { 6 users.each({:@name => "Tom Jones"}) {|seller| 7 items.each({:@offered_by => seller[:@userid], :@description => /Bicycle/}) {|item| 8 bids.each({:@itemno => item[:@itemno]}) {|highbid| 9 users.each({:@userid => highbid[:@userid]}) {|buyer| 10 best_bid = bids.find_all{|b| b.is_a? XML and b[:@itemno] == item[:@itemno]}.map{|b| b[:@bid].to_i}.max 11 next unless highbid[:@bid].to_i == best_bid 12 13 jones_bike! { 14 add! item.child(:itemno) 15 add! item.child(:description) 16 high_bid! highbid.child(:bid) 17 high_bidder! buyer.child(:name) 18 } 19 } 20 } 21 } 22 } 23 }
<result> { for $seller in doc("users.xml")//user_tuple, $buyer in doc("users.xml")//user_tuple, $item in doc("items.xml")//item_tuple, $highbid in doc("bids.xml")//bid_tuple where $seller/name = "Tom Jones" and $seller/userid = $item/offered_by and contains($item/description , "Bicycle") and $item/itemno = $highbid/itemno and $highbid/userid = $buyer/userid and $highbid/bid = max( doc("bids.xml")//bid_tuple [itemno = $item/itemno]/bid ) order by ($item/itemno) return <jones_bike> { $item/itemno } { $item/description } <high_bid>{ $highbid/bid }</high_bid> <high_bidder>{ $buyer/name }</high_bidder> </jones_bike> } </result>
1 <result> 2 <jones_bike> 3 <itemno>1001</itemno> 4 <description>Red Bicycle</description> 5 <high_bid> 6 <bid>55</bid> 7 </high_bid> 8 <high_bidder> 9 <name>Mary Doe</name> 10 </high_bidder> 11 </jones_bike> 12 </result>
For each item whose highest bid is more than twice its reserve price, list the item number, description, reserve price, and highest bid.
1 items = XML.load('items.xml') 2 bids = XML.load('bids.xml') 3 4 XML.result! { 5 items.each(XML){|item| 6 z = bids.find_all{|b| b.is_a? XML and b[:@itemno] == item[:@itemno]}.map{|b| b[:@bid].to_i}.max 7 next unless z and item[:@reserve_price].to_i * 2 < z 8 successful_item! { 9 add! item.child(:itemno) 10 add! item.child(:description) 11 add! item.child(:reserve_price) 12 high_bid! z 13 } 14 } 15 }
<result> { for $item in doc("items.xml")//item_tuple let $b := doc("bids.xml")//bid_tuple[itemno = $item/itemno] let $z := max($b/bid) where $item/reserve_price * 2 < $z return <successful_item> { $item/itemno } { $item/description } { $item/reserve_price } <high_bid>{$z }</high_bid> </successful_item> } </result>
1 <result> 2 <successful_item> 3 <itemno>1002</itemno> 4 <description>Motorcycle</description> 5 <reserve_price>500</reserve_price> 6 <high_bid>1200</high_bid> 7 </successful_item> 8 <successful_item> 9 <itemno>1004</itemno> 10 <description>Tricycle</description> 11 <reserve_price>15</reserve_price> 12 <high_bid>40</high_bid> 13 </successful_item> 14 </result>
Find the highest bid ever made for a bicycle or tricycle.
1 items = XML.load('items.xml') 2 bids = XML.load('bids.xml') 3 4 allbikes = items.children({:@description => /Bicycle|Tricycle/}).map{|item| item[:@itemno]} 5 6 XML.high_bid! { 7 add! bids.find_all{|b| b.is_a? XML and allbikes.include? b[:@itemno]}.map{|b| b[:@bid].to_i}.max 8 }
let $allbikes := doc("items.xml")//item_tuple [contains(description, "Bicycle") or contains(description, "Tricycle")] let $bikebids := doc("bids.xml")//bid_tuple[itemno = $allbikes/itemno] return <high_bid> { max($bikebids/bid) } </high_bid>
1 <high_bid>225</high_bid>
How many items were actioned (auction ended) in March 1999?
1 XML.item_count! XML.load('items.xml').find_all{|item| item.is_a? XML and item[:@end_day] =~ /^1999-03/}.size
let $item := doc("items.xml")//item_tuple [end_date >= xs:date("1999-03-01") and end_date <= xs:date("1999-03-31")] return <item_count> { count($item) } </item_count>
1 <item_count>3</item_count>
List the number of items auctioned each month in 1999 for which data is available, ordered by month.
1 items = XML.load('items.xml').children(:item_tuple) 2 3 XML.result! { 4 items.map{|item| item[:@end_day] =~ /^1999-(\d+)/; $1.to_i}.sort.uniq.each{|m| 5 monthly_result! { 6 month! m 7 item_count!(items.find_all{|item| item[:@end_day] =~ /1999-(\d+)/; $1.to_i==m}.size) 8 } 9 } 10 }
<result> { let $end_dates := doc("items.xml")//item_tuple/end_date for $m in distinct-values(for $e in $end_dates return month-from-date($e)) let $item := doc("items.xml") //item_tuple[year-from-date(end_date) = 1999 and month-from-date(end_date) = $m] order by $m return <monthly_result> <month>{ $m }</month> <item_count>{ count($item) }</item_count> </monthly_result> } </result>
1 <result> 2 <monthly_result> 3 <month>1</month> 4 <item_count>1</item_count> 5 </monthly_result> 6 <monthly_result> 7 <month>2</month> 8 <item_count>2</item_count> 9 </monthly_result> 10 <monthly_result> 11 <month>3</month> 12 <item_count>3</item_count> 13 </monthly_result> 14 <monthly_result> 15 <month>4</month> 16 <item_count>1</item_count> 17 </monthly_result> 18 <monthly_result> 19 <month>5</month> 20 <item_count>1</item_count> 21 </monthly_result> 22 </result>
For each item that has received a bid, list the item number, the highest bid, and the name of the highest bidder, ordered by item number.
1 users = XML.load('users.xml') 2 bids = XML.load('bids.xml').sort_by{|b| b[:@itemno].to_i} 3 4 XML.result! { 5 bids.each{|highbid| 6 next if bids.any?{|b| b[:@itemno] == highbid[:@itemno] and b[:@bid].to_i > highbid[:@bid].to_i} 7 users.children({:@userid => highbid[:@userid]}){|user| 8 high_bid! { 9 add! highbid.child(:itemno) 10 add! highbid.child(:bid) 11 bidder! user[:@name] 12 } 13 } 14 } 15 }
<result> { for $highbid in doc("bids.xml")//bid_tuple, $user in doc("users.xml")//user_tuple where $user/userid = $highbid/userid and $highbid/bid = max(doc("bids.xml")//bid_tuple[itemno=$highbid/itemno]/bid) order by $highbid/itemno return <high_bid> { $highbid/itemno } { $highbid/bid } <bidder>{ $user/name/text() }</bidder> </high_bid> } </result>
1 <result> 2 <high_bid> 3 <itemno>1001</itemno> 4 <bid>55</bid> 5 <bidder>Mary Doe</bidder> 6 </high_bid> 7 <high_bid> 8 <itemno>1002</itemno> 9 <bid>1200</bid> 10 <bidder>Mary Doe</bidder> 11 </high_bid> 12 <high_bid> 13 <itemno>1003</itemno> 14 <bid>20</bid> 15 <bidder>Jack Sprat</bidder> 16 </high_bid> 17 <high_bid> 18 <itemno>1004</itemno> 19 <bid>40</bid> 20 <bidder>Tom Jones</bidder> 21 </high_bid> 22 <high_bid> 23 <itemno>1007</itemno> 24 <bid>225</bid> 25 <bidder>Roger Smith</bidder> 26 </high_bid> 27 </result>
List the item number and description of the item(s) that received the highest bid ever recorded, and the amount of that bid.
1 items = XML.load('items.xml') 2 bids = XML.load('bids.xml') 3 4 highbid = bids.children.children(:bid).map{|b| b.text.to_i}.max.to_s 5 6 XML.result! { 7 items.each(XML){|item| 8 bids.each({:@itemno => item[:@itemno], :@bid => highbid}) {|b| 9 expensive_item! { 10 add! item.child(:itemno) 11 add! item.child(:description) 12 high_bid! highbid 13 } 14 } 15 } 16 }
let $highbid := max(doc("bids.xml")//bid_tuple/bid) return <result> { for $item in doc("items.xml")//item_tuple, $b in doc("bids.xml")//bid_tuple[itemno = $item/itemno] where $b/bid = $highbid return <expensive_item> { $item/itemno } { $item/description } <high_bid>{ $highbid }</high_bid> </expensive_item> } </result>
1 <result> 2 <expensive_item> 3 <itemno>1002</itemno> 4 <description>Motorcycle</description> 5 <high_bid>1200</high_bid> 6 </expensive_item> 7 </result>
List the item number and description of the item(s) that received the largest number of bids, and the number of bids it (or they) received.
1 items = XML.load('items.xml') 2 bids = XML.load('bids.xml').children(:bid_tuple) 3 4 XML.result! { 5 bids_per_item = Hash.new([]) 6 bids.each{|bid| 7 bids_per_item[bid[:@itemno]] += [bid] 8 } 9 max_bid_count = bids_per_item.map{|k,v| v.size}.max 10 11 items.each(XML){|item| 12 next unless bids_per_item[item[:@itemno]].size == max_bid_count 13 popular_item! { 14 add! item.child(:itemno) 15 add! item.child(:description) 16 bid_count! max_bid_count 17 } 18 } 19 }
declare function local:bid_summary() as element()* { for $i in distinct-values(doc("bids.xml")//itemno) let $b := doc("bids.xml")//bid_tuple[itemno = $i] return <bid_count> <itemno>{ $i }</itemno> <nbids>{ count($b) }</nbids> </bid_count> }; <result> { let $bid_counts := local:bid_summary(), $maxbids := max($bid_counts/nbids), $maxitemnos := $bid_counts[nbids = $maxbids] for $item in doc("items.xml")//item_tuple, $bc in $bid_counts where $bc/nbids = $maxbids and $item/itemno = $bc/itemno return <popular_item> { $item/itemno } { $item/description } <bid_count>{ $bc/nbids/text() }</bid_count> </popular_item> } </result>
1 <result> 2 <popular_item> 3 <itemno>1001</itemno> 4 <description>Red Bicycle</description> 5 <bid_count>5</bid_count> 6 </popular_item> 7 <popular_item> 8 <itemno>1002</itemno> 9 <description>Motorcycle</description> 10 <bid_count>5</bid_count> 11 </popular_item> 12 </result>
For each user who has placed a bid, give the userid, name, number of bids, and average bid, in order by userid.
1 users = XML.load('users.xml') 2 bids = XML.load('bids.xml') 3 4 XML.result! { 5 bids.descendants(:userid).map{|uid| uid.text}.uniq.sort.each{|uid| 6 users.each({:@userid => uid}){|u| 7 user_bids = bids.find_all{|b| b.is_a? XML and b[:@userid] == uid} 8 bidder! { 9 add! u.child(:userid) 10 add! u.child(:name) 11 bidcount! user_bids.size 12 sum = 0.0 13 user_bids.each{|b| 14 sum += b[:@bid].to_i 15 } 16 a = sum / user_bids.size 17 a = a.to_i if a.to_i == a 18 avgbid! a 19 } 20 } 21 } 22 }
<result> { for $uid in distinct-values(doc("bids.xml")//userid), $u in doc("users.xml")//user_tuple[userid = $uid] let $b := doc("bids.xml")//bid_tuple[userid = $uid] order by $u/userid return <bidder> { $u/userid } { $u/name } <bidcount>{ count($b) }</bidcount> <avgbid>{ avg($b/bid) }</avgbid> </bidder> } </result>
1 <result> 2 <bidder> 3 <userid>U01</userid> 4 <name>Tom Jones</name> 5 <bidcount>2</bidcount> 6 <avgbid>220</avgbid> 7 </bidder> 8 <bidder> 9 <userid>U02</userid> 10 <name>Mary Doe</name> 11 <bidcount>5</bidcount> 12 <avgbid>387</avgbid> 13 </bidder> 14 <bidder> 15 <userid>U03</userid> 16 <name>Dee Linquent</name> 17 <bidcount>2</bidcount> 18 <avgbid>487.5</avgbid> 19 </bidder> 20 <bidder> 21 <userid>U04</userid> 22 <name>Roger Smith</name> 23 <bidcount>5</bidcount> 24 <avgbid>266</avgbid> 25 </bidder> 26 <bidder> 27 <userid>U05</userid> 28 <name>Jack Sprat</name> 29 <bidcount>2</bidcount> 30 <avgbid>110</avgbid> 31 </bidder> 32 </result>
List item numbers and average bids for items that have received three or more bids, in descending order by average bid.
1 bids = XML.load('bids.xml').children(:bid_tuple) 2 3 XML.result! { 4 bids_of_item = Hash.new([]) 5 sum_bids_of_item = Hash.new(0.0) 6 bids.each{|b| 7 i = b[:@itemno] 8 bids_of_item[i] += [b] 9 sum_bids_of_item[i] += b[:@bid].to_i 10 } 11 bids_of_item.find_all{|i,b| b.size >= 3}.map{|i,b| [sum_bids_of_item[i] / b.size, i, b]}.sort.reverse.each{|a,i,b| 12 popular_item! { 13 itemno! i 14 a = a.to_i if a.to_i == a 15 avgbid! a 16 } 17 18 } 19 }
<result> { for $i in distinct-values(doc("bids.xml")//itemno) let $b := doc("bids.xml")//bid_tuple[itemno = $i] let $avgbid := avg($b/bid) where count($b) >= 3 order by $avgbid descending return <popular_item> <itemno>{ $i }</itemno> <avgbid>{ $avgbid }</avgbid> </popular_item> } </result>
1 <result> 2 <popular_item> 3 <itemno>1002</itemno> 4 <avgbid>800</avgbid> 5 </popular_item> 6 <popular_item> 7 <itemno>1007</itemno> 8 <avgbid>200</avgbid> 9 </popular_item> 10 <popular_item> 11 <itemno>1001</itemno> 12 <avgbid>45</avgbid> 13 </popular_item> 14 </result>
List names of users who have placed multiple bids of at least $100 each.
1 users = XML.load('users.xml') 2 bids = XML.load('bids.xml') 3 4 XML.result! { 5 users.each(XML){|u| 6 next unless bids.find_all{|b| b.is_a? XML and b[:@userid] == u[:@userid] and b[:@bid].to_i >= 100 }.size > 1 7 big_spender! u[:@name] 8 } 9 }
<result> { for $u in doc("users.xml")//user_tuple let $b := doc("bids.xml")//bid_tuple[userid=$u/userid and bid>=100] where count($b) > 1 return <big_spender>{ $u/name/text() }</big_spender> } </result>
1 <result> 2 <big_spender>Mary Doe</big_spender> 3 <big_spender>Dee Linquent</big_spender> 4 <big_spender>Roger Smith</big_spender> 5 </result>
List all registered users in order by userid; for each user, include the userid, name, and an indication of whether the user is active (has at least one bid on record) or inactive (has no bid on record).
1 users = XML.load('users.xml').sort_by{|i| i[:@userid].to_i} 2 bids = XML.load('bids.xml') 3 4 XML.result! { 5 users.each(XML){|u| 6 user_bids = bids.children({:@userid => u[:@userid]}) 7 user! { 8 add! u.child(:userid) 9 add! u.child(:name) 10 status! (user_bids.empty? ? 'inactive' : 'active') 11 } 12 } 13 }
<result> { for $u in doc("users.xml")//user_tuple let $b := doc("bids.xml")//bid_tuple[userid = $u/userid] order by $u/userid return <user> { $u/userid } { $u/name } { if (empty($b)) then <status>inactive</status> else <status>active</status> } </user> } </result>
1 2 3 <result> 4 <user> 5 <userid>U01</userid> 6 <name>Tom Jones</name> 7 <status>active</status> 8 </user> 9 <user> 10 <userid>U02</userid> 11 <name>Mary Doe</name> 12 <status>active</status> 13 </user> 14 <user> 15 <userid>U03</userid> 16 <name>Dee Linquent</name> 17 <status>active</status> 18 </user> 19 <user> 20 <userid>U04</userid> 21 <name>Roger Smith</name> 22 <status>active</status> 23 </user> 24 <user> 25 <userid>U05</userid> 26 <name>Jack Sprat</name> 27 <status>active</status> 28 </user> 29 <user> 30 <userid>U06</userid> 31 <name>Rip Van Winkle</name> 32 <status>inactive</status> 33 </user> 34 </result> 35
List the names of users, if any, who have bid on every item.
1 users = XML.load('users.xml') 2 items = XML.load('items.xml') 3 bids = XML.load('bids.xml') 4 5 XML.frequent_bidder! { 6 users.each(XML){|u| 7 next unless items.all?{|item| 8 (!item.is_a? XML) or 9 bids.any?{|b| b.is_a? XML and item[:@itemno] == b[:@itemno] and u[:@userid] == b[:@userid]} 10 } 11 add! u.child(:name) 12 } 13 }
<frequent_bidder> { for $u in doc("users.xml")//user_tuple where every $item in doc("items.xml")//item_tuple satisfies some $b in doc("bids.xml")//bid_tuple satisfies ($item/itemno = $b/itemno and $u/userid = $b/userid) return $u/name } </frequent_bidder>
1 <frequent_bidder />
List all users in alphabetic order by name. For each user, include descriptions of all the items (if any) that were bid on by that user, in alphabetic order.
1 users = XML.load('users.xml').children(:user_tuple).sort_by{|i| i[:@name]} 2 items = XML.load('items.xml') 3 bids = XML.load('bids.xml') 4 5 XML.result! { 6 users.each{|u| 7 user! { 8 add! u.child(:name) 9 bids.find_all{|b| 10 b.is_a? XML and b[:@userid] == u[:@userid] 11 }.map{|b| b[:@itemno]}.uniq.map{|b| 12 items.find{|i| i.is_a? XML and i[:@itemno] == b}[:@description] 13 }.sort.each{|dsc| 14 bid_on_item! dsc 15 } 16 } 17 } 18 }
<result> { for $u in doc("users.xml")//user_tuple order by $u/name return <user> { $u/name } { for $b in distinct-values(doc("bids.xml")//bid_tuple [userid = $u/userid]/itemno) for $i in doc("items.xml")//item_tuple[itemno = $b] let $descr := $i/description/text() order by $descr return <bid_on_item>{ $descr }</bid_on_item> } </user> } </result>
1 <result> 2 <user> 3 <name>Dee Linquent</name> 4 <bid_on_item>Motorcycle</bid_on_item> 5 <bid_on_item>Racing Bicycle</bid_on_item> 6 </user> 7 <user> 8 <name>Jack Sprat</name> 9 <bid_on_item>Old Bicycle</bid_on_item> 10 <bid_on_item>Racing Bicycle</bid_on_item> 11 </user> 12 <user> 13 <name>Mary Doe</name> 14 <bid_on_item>Motorcycle</bid_on_item> 15 <bid_on_item>Red Bicycle</bid_on_item> 16 </user> 17 <user> 18 <name>Rip Van Winkle</name> 19 </user> 20 <user> 21 <name>Roger Smith</name> 22 <bid_on_item>Motorcycle</bid_on_item> 23 <bid_on_item>Old Bicycle</bid_on_item> 24 <bid_on_item>Racing Bicycle</bid_on_item> 25 <bid_on_item>Red Bicycle</bid_on_item> 26 </user> 27 <user> 28 <name>Tom Jones</name> 29 <bid_on_item>Motorcycle</bid_on_item> 30 <bid_on_item>Tricycle</bid_on_item> 31 </user> 32 </result>
1 <report> 2 <section> 3 <section.title>Procedure</section.title> 4 <section.content> 5 The patient was taken to the operating room where she was placed 6 in supine position and 7 <anesthesia>induced under general anesthesia.</anesthesia> 8 <prep> 9 <action>A Foley catheter was placed to decompress the bladder</action> 10 and the abdomen was then prepped and draped in sterile fashion. 11 </prep> 12 <incision> 13 A curvilinear incision was made 14 <geography>in the midline immediately infraumbilical</geography> 15 and the subcutaneous tissue was divided 16 <instrument>using electrocautery.</instrument> 17 </incision> 18 The fascia was identified and 19 <action>#2 0 Maxon stay sutures were placed on each side of the midline. 20 </action> 21 <incision> 22 The fascia was divided using 23 <instrument>electrocautery</instrument> 24 and the peritoneum was entered. 25 </incision> 26 <observation>The small bowel was identified.</observation> 27 and 28 <action> 29 the 30 <instrument>Hasson trocar</instrument> 31 was placed under direct visualization. 32 </action> 33 <action> 34 The 35 <instrument>trocar</instrument> 36 was secured to the fascia using the stay sutures. 37 </action> 38 </section.content> 39 </section> 40 </report>
In the Procedure section of Report1, what Instruments were used in the second Incision?
1 XML.load('report1.xml').descendants(:section) {|s| 2 print s.descendants(:incision)[1].child(:instrument) if s[:"@section.title"] == "Procedure" 3 }
for $s in doc("report1.xml")//section[section.title = "Procedure"] return ($s//incision)[2]/instrument
1 <instrument>electrocautery</instrument>
In the Procedure section of Report1, what are the first two Instruments to be used?
1 XML.load('report1.xml').descendants(:section) {|s| 2 print s.descendants(:instrument)[0,2] if s[:"@section.title"] == "Procedure" 3 }
for $s in doc("report1.xml")//section[section.title = "Procedure"] return ($s//instrument)[position()<=2]
1 <instrument>using electrocautery.</instrument> 2 <instrument>electrocautery</instrument>
In Report1, what Instruments were used in the first two Actions after the second Incision?
1 doc = XML.load('report1.xml') 2 i2 = doc.descendants(:incision)[1] 3 4 print doc.range(i2,nil).descendants(:action)[0,2].children(:instrument)
let $i2 := (doc("report1.xml")//incision)[2] for $a in (doc("report1.xml")//action)[. >> $i2][position()<=2] return $a//instrument
1 <instrument>Hasson trocar</instrument> 2 <instrument>trocar</instrument>
In Report1, find "Procedure" sections where no Anesthesia element occurs before the first Incision
1 XML.load('report1.xml').descendants(:section) {|p| 2 next unless p[:"@section.title"] == "Procedure" 3 i1 = p.descendants(:incision)[0] 4 print p if p.range(nil,i1).descendants(:anesthesia).size == 0 5 }
for $p in doc("report1.xml")//section[section.title = "Procedure"] where not(some $a in $p//anesthesia satisfies $a << ($p//incision)[1] ) return $p
1
In Report1, what happened between the first Incision and the second Incision?
1 XML.critical_sequence! { 2 p = XML.load('report1.xml').descendants(:section).find {|p| p[:"@section.title"] == "Procedure"} 3 i1,i2, = *p.descendants(:incision) 4 add! p.subsequence(i1,i2).map{|p| [p] + [p].descendants} 5 }
<critical_sequence> { let $proc := doc("report1.xml")//section[section.title="Procedure"][1], $i1 := ($proc//incision)[1], $i2 := ($proc//incision)[2] for $n in $proc//node() except $i1//node() where $n >> $i1 and $n << $i2 return $n } </critical_sequence>
1 <critical_sequence> 2 The fascia was identified and 3 <action>#2 0 Maxon stay sutures were placed on each side of the midline. 4 </action>#2 0 Maxon stay sutures were placed on each side of the midline. 5 </critical_sequence>
1 <!DOCTYPE report SYSTEM "report.dtd"> 2 <report> 3 <title>Getting started with SGML</title> 4 <chapter> 5 <title>The business challenge</title> 6 <intro> 7 <para>With the ever-changing and growing global market, companies and 8 large organizations are searching for ways to become more viable and 9 competitive. Downsizing and other cost-cutting measures demand more 10 efficient use of corporate resources. One very important resource is 11 an organization's information.</para> 12 <para>As part of the move toward integrated information management, 13 whole industries are developing and implementing standards for 14 exchanging technical information. This report describes how one such 15 standard, the Standard Generalized Markup Language (SGML), works as 16 part of an overall information management strategy.</para> 17 <graphic graphname="infoflow"/></intro></chapter> 18 <chapter> 19 <title>Getting to know SGML</title> 20 <intro> 21 <para>While SGML is a fairly recent technology, the use of 22 <emph>markup</emph> in computer-generated documents has existed for a 23 while.</para></intro> 24 <section shorttitle="What is markup?"> 25 <title>What is markup, or everything you always wanted to know about 26 document preparation but were afraid to ask?</title> 27 <intro> 28 <para>Markup is everything in a document that is not content. The 29 traditional meaning of markup is the manual <emph>marking</emph> up 30 of typewritten text to give instructions for a typesetter or 31 compositor about how to fit the text on a page and what typefaces to 32 use. This kind of markup is known as <emph>procedural markup</emph>.</para></intro> 33 <topic topicid="top1"> 34 <title>Procedural markup</title> 35 <para>Most electronic publishing systems today use some form of 36 procedural markup. Procedural markup codes are good for one 37 presentation of the information.</para></topic> 38 <topic topicid="top2"> 39 <title>Generic markup</title> 40 <para>Generic markup (also known as descriptive markup) describes the 41 <emph>purpose</emph> of the text in a document. A basic concept of 42 generic markup is that the content of a document must be separate from 43 the style. Generic markup allows for multiple presentations of the 44 information.</para></topic> 45 <topic topicid="top3"> 46 <title>Drawbacks of procedural markup</title> 47 <para>Industries involved in technical documentation increasingly 48 prefer generic over procedural markup schemes. When a company changes 49 software or hardware systems, enormous data translation tasks arise, 50 often resulting in errors.</para></topic></section> 51 <section shorttitle="What is SGML?"> 52 <title>What <emph>is</emph> SGML in the grand scheme of the universe, anyway?</title> 53 <intro> 54 <para>SGML defines a strict markup scheme with a syntax for defining 55 document data elements and an overall framework for marking up 56 documents.</para> 57 <para>SGML can describe and create documents that are not dependent on 58 any hardware, software, formatter, or operating system. Since SGML documents 59 conform to an international standard, they are portable.</para></intro></section> 60 <section shorttitle="How does SGML work?"> 61 <title>How is SGML and would you recommend it to your grandmother?</title> 62 <intro> 63 <para>You can break a typical document into three layers: structure, 64 content, and style. SGML works by separating these three aspects and 65 deals mainly with the relationship between structure and content.</para></intro> 66 <topic topicid="top4"> 67 <title>Structure</title> 68 <para>At the heart of an SGML application is a file called the DTD, or 69 Document Type Definition. The DTD sets up the structure of a document, 70 much like a database schema describes the types of information it 71 handles.</para> 72 <para>A database schema also defines the relationships between the 73 various types of data. Similarly, a DTD specifies <emph>rules</emph> 74 to help ensure documents have a consistent, logical structure.</para></topic> 75 <topic topicid="top5"> 76 <title>Content</title> 77 <para>Content is the information itself. The method for identifying 78 the information and its meaning within this framework is called 79 <emph>tagging</emph>. Tagging must 80 conform to the rules established in the DTD (see <xref xrefid="top4"/>).</para> 81 <graphic graphname="tagexamp"/></topic> 82 <topic topicid="top6"> 83 <title>Style</title> 84 <para>SGML does not standardize style or other processing methods for 85 information stored in SGML.</para></topic></section></chapter> 86 <chapter> 87 <title>Resources</title> 88 <section> 89 <title>Conferences, tutorials, and training</title> 90 <intro> 91 <para>The Graphic Communications Association has been 92 instrumental in the development of SGML. GCA provides conferences, 93 tutorials, newsletters, and publication sales for both members and 94 non-members.</para> 95 <para security="c">Exiled members of the former Soviet Union's secret 96 police, the KGB, have infiltrated the upper ranks of the GCA and are 97 planning the Final Revolution as soon as DSSSL is completed.</para> 98 </intro> 99 </section> 100 </chapter> 101 </report>
Locate all paragraphs in the report (all "para" elements occurring anywhere within the "report" element).
1 XML.result!(XML.load('sgml.xml').descendants(:para))
<result> { doc("sgml.xml")//report//para } </result>
1 <result><para>With the ever-changing and growing global market, companies and 2 large organizations are searching for ways to become more viable and 3 competitive. Downsizing and other cost-cutting measures demand more 4 efficient use of corporate resources. One very important resource is 5 an organization's information.</para><para>As part of the move toward integrated information management, 6 whole industries are developing and implementing standards for 7 exchanging technical information. This report describes how one such 8 standard, the Standard Generalized Markup Language (SGML), works as 9 part of an overall information management strategy.</para><para>While SGML is a fairly recent technology, the use of 10 <emph>markup</emph> in computer-generated documents has existed for a 11 while.</para><para>Markup is everything in a document that is not content. The 12 traditional meaning of markup is the manual <emph>marking</emph> up 13 of typewritten text to give instructions for a typesetter or 14 compositor about how to fit the text on a page and what typefaces to 15 use. This kind of markup is known as <emph>procedural markup</emph>.</para><para>Most electronic publishing systems today use some form of 16 procedural markup. Procedural markup codes are good for one 17 presentation of the information.</para><para>Generic markup (also known as descriptive markup) describes the 18 <emph>purpose</emph> of the text in a document. A basic concept of 19 generic markup is that the content of a document must be separate from 20 the style. Generic markup allows for multiple presentations of the 21 information.</para><para>Industries involved in technical documentation increasingly 22 prefer generic over procedural markup schemes. When a company changes 23 software or hardware systems, enormous data translation tasks arise, 24 often resulting in errors.</para><para>SGML defines a strict markup scheme with a syntax for defining 25 document data elements and an overall framework for marking up 26 documents.</para><para>SGML can describe and create documents that are not dependent on 27 any hardware, software, formatter, or operating system. Since SGML documents 28 conform to an international standard, they are portable.</para><para>You can break a typical document into three layers: structure, 29 content, and style. SGML works by separating these three aspects and 30 deals mainly with the relationship between structure and content.</para><para>At the heart of an SGML application is a file called the DTD, or 31 Document Type Definition. The DTD sets up the structure of a document, 32 much like a database schema describes the types of information it 33 handles.</para><para>A database schema also defines the relationships between the 34 various types of data. Similarly, a DTD specifies <emph>rules</emph> 35 to help ensure documents have a consistent, logical structure.</para><para>Content is the information itself. The method for identifying 36 the information and its meaning within this framework is called 37 <emph>tagging</emph>. Tagging must 38 conform to the rules established in the DTD (see <xref xrefid='top4'/>).</para><para>SGML does not standardize style or other processing methods for 39 information stored in SGML.</para><para>The Graphic Communications Association has been 40 instrumental in the development of SGML. GCA provides conferences, 41 tutorials, newsletters, and publication sales for both members and 42 non-members.</para><para security='c'>Exiled members of the former Soviet Union's secret 43 police, the KGB, have infiltrated the upper ranks of the GCA and are 44 planning the Final Revolution as soon as DSSSL is completed.</para></result>
Locate all paragraph elements in an introduction (all "para" elements directly contained within an "intro" element).
1 puts XML.result(XML.load('sgml.xml').descendants(:intro, :para))
<result> { doc("sgml.xml")//intro/para } </result>
1 <result><para>With the ever-changing and growing global market, companies and 2 large organizations are searching for ways to become more viable and 3 competitive. Downsizing and other cost-cutting measures demand more 4 efficient use of corporate resources. One very important resource is 5 an organization's information.</para><para>As part of the move toward integrated information management, 6 whole industries are developing and implementing standards for 7 exchanging technical information. This report describes how one such 8 standard, the Standard Generalized Markup Language (SGML), works as 9 part of an overall information management strategy.</para><para>While SGML is a fairly recent technology, the use of 10 <emph>markup</emph> in computer-generated documents has existed for a 11 while.</para><para>Markup is everything in a document that is not content. The 12 traditional meaning of markup is the manual <emph>marking</emph> up 13 of typewritten text to give instructions for a typesetter or 14 compositor about how to fit the text on a page and what typefaces to 15 use. This kind of markup is known as <emph>procedural markup</emph>.</para><para>SGML defines a strict markup scheme with a syntax for defining 16 document data elements and an overall framework for marking up 17 documents.</para><para>SGML can describe and create documents that are not dependent on 18 any hardware, software, formatter, or operating system. Since SGML documents 19 conform to an international standard, they are portable.</para><para>You can break a typical document into three layers: structure, 20 content, and style. SGML works by separating these three aspects and 21 deals mainly with the relationship between structure and content.</para><para>The Graphic Communications Association has been 22 instrumental in the development of SGML. GCA provides conferences, 23 tutorials, newsletters, and publication sales for both members and 24 non-members.</para><para security='c'>Exiled members of the former Soviet Union's secret 25 police, the KGB, have infiltrated the upper ranks of the GCA and are 26 planning the Final Revolution as soon as DSSSL is completed.</para></result>
Locate all paragraphs in the introduction of a section that is in a chapter that has no introduction (all "para" elements directly contained within an "intro" element directly contained in a "section" element directly contained in a "chapter" element. The "chapter" element must not directly contain an "intro" element).
1 XML.result! { 2 XML.load('sgml.xml').descendants(:chapter) {|c| 3 next unless c.children(:intro).empty? 4 add! c.children(:section, :intro, :para) 5 } 6 }
<result> { for $c in doc("sgml.xml")//chapter where empty($c/intro) return $c/section/intro/para } </result>
1 <result><para>The Graphic Communications Association has been 2 instrumental in the development of SGML. GCA provides conferences, 3 tutorials, newsletters, and publication sales for both members and 4 non-members.</para><para security='c'>Exiled members of the former Soviet Union's secret 5 police, the KGB, have infiltrated the upper ranks of the GCA and are 6 planning the Final Revolution as soon as DSSSL is completed.</para></result>
Locate the second paragraph in the third section in the second chapter (the second "para" element occurring in the third "section" element occurring in the second "chapter" element occurring in the "report").
1 XML.result!( 2 XML.load('sgml.xml').descendants(:chapter)[1].descendants(:section)[2].descendants(:para)[1] 3 )
<result> { (((doc("sgml.xml")//chapter)[2]//section)[3]//para)[2] } </result>
1 <result><para>At the heart of an SGML application is a file called the DTD, or 2 Document Type Definition. The DTD sets up the structure of a document, 3 much like a database schema describes the types of information it 4 handles.</para></result>
Locate all classified paragraphs (all "para" elements whose "security" attribute has the value "c").
1 XML.result!(XML.load('sgml.xml').descendants(:para).find_all{|p| p[:security] == 'c'})
<result> { doc("sgml.xml")//para[@security = "c"] } </result>
1 <result><para security='c'>Exiled members of the former Soviet Union's secret 2 police, the KGB, have infiltrated the upper ranks of the GCA and are 3 planning the Final Revolution as soon as DSSSL is completed.</para></result>
List the short titles of all sections (the values of the "shorttitle" attributes of all "section" elements, expressing each short title as the value of a new element.)
1 XML.result! { 2 XML.load('sgml.xml').descendants(:section).each{|s| 3 stitle! s[:shorttitle] 4 } 5 }
<result> { for $s in doc("sgml.xml")//section/@shorttitle return <stitle>{ $s }</stitle> } </result>
1 <result><stitle>What is markup?</stitle><stitle>What is SGML?</stitle><stitle>How does SGML work?</stitle><stitle/></result>
Locate the initial letter of the initial paragraph of all introductions (the first character in the content [character content as well as element content] of the first "para" element contained in an "intro" element).
1 XML.result! { 2 XML.load('sgml.xml').descendants(:intro) {|i| 3 first_letter! i.children(:para)[0].text[0,1] 4 } 5 }
<result> { for $i in doc("sgml.xml")//intro/para[1] return <first_letter>{ substring(string($i), 1, 1) }</first_letter> } </result>
1 <result><first_letter>W</first_letter><first_letter>W</first_letter><first_letter>M</first_letter><first_letter>S</first_letter><first_letter>Y</first_letter><first_letter>T</first_letter></result>
Locate all sections with a title that has "is SGML" in it. The string may occur anywhere in the descendants of the title element, and markup boundaries are ignored.
1 XML.result! { 2 XML.load('sgml.xml').descendants(:section) {|s| 3 add! s if s.descendants(:title).any?{|t| t =~ /is SGML/} 4 } 5 }
<result> { doc("sgml.xml")//section[.//title[contains(., "is SGML")]] } </result>
1 <result><section shorttitle='What is SGML?'> 2 <title>What <emph>is</emph> SGML in the grand scheme of the universe, anyway?</title> 3 <intro> 4 <para>SGML defines a strict markup scheme with a syntax for defining 5 document data elements and an overall framework for marking up 6 documents.</para> 7 <para>SGML can describe and create documents that are not dependent on 8 any hardware, software, formatter, or operating system. Since SGML documents 9 conform to an international standard, they are portable.</para></intro></section><section shorttitle='How does SGML work?'> 10 <title>How is SGML and would you recommend it to your grandmother?</title> 11 <intro> 12 <para>You can break a typical document into three layers: structure, 13 content, and style. SGML works by separating these three aspects and 14 deals mainly with the relationship between structure and content.</para></intro> 15 <topic topicid='top4'> 16 <title>Structure</title> 17 <para>At the heart of an SGML application is a file called the DTD, or 18 Document Type Definition. The DTD sets up the structure of a document, 19 much like a database schema describes the types of information it 20 handles.</para> 21 <para>A database schema also defines the relationships between the 22 various types of data. Similarly, a DTD specifies <emph>rules</emph> 23 to help ensure documents have a consistent, logical structure.</para></topic> 24 <topic topicid='top5'> 25 <title>Content</title> 26 <para>Content is the information itself. The method for identifying 27 the information and its meaning within this framework is called 28 <emph>tagging</emph>. Tagging must 29 conform to the rules established in the DTD (see <xref xrefid='top4'/>).</para> 30 <graphic graphname='tagexamp'/></topic> 31 <topic topicid='top6'> 32 <title>Style</title> 33 <para>SGML does not standardize style or other processing methods for 34 information stored in SGML.</para></topic></section></result>
Same as (Q8a), but the string "is SGML" cannot be interrupted by sub-elements, and must appear in a single text node.
1 XML.result! { 2 doc = XML.load('sgml.xml') 3 doc.normalize! 4 doc.descendants(:section) {|s| 5 add! s if s.descendants(:title).any?{|t| 6 t.descendants.any?{|d| d.is_a? String and d =~ /is SGML/} 7 } 8 } 9 }
<result> { doc("sgml.xml")//section[.//title/text()[contains(., "is SGML")]] } </result>
1 <result><section shorttitle='How does SGML work?'> 2 <title>How is SGML and would you recommend it to your grandmother?</title> 3 <intro> 4 <para>You can break a typical document into three layers: structure, 5 content, and style. SGML works by separating these three aspects and 6 deals mainly with the relationship between structure and content.</para></intro> 7 <topic topicid='top4'> 8 <title>Structure</title> 9 <para>At the heart of an SGML application is a file called the DTD, or 10 Document Type Definition. The DTD sets up the structure of a document, 11 much like a database schema describes the types of information it 12 handles.</para> 13 <para>A database schema also defines the relationships between the 14 various types of data. Similarly, a DTD specifies <emph>rules</emph> 15 to help ensure documents have a consistent, logical structure.</para></topic> 16 <topic topicid='top5'> 17 <title>Content</title> 18 <para>Content is the information itself. The method for identifying 19 the information and its meaning within this framework is called 20 <emph>tagging</emph>. Tagging must 21 conform to the rules established in the DTD (see <xref xrefid='top4'/>).</para> 22 <graphic graphname='tagexamp'/></topic> 23 <topic topicid='top6'> 24 <title>Style</title> 25 <para>SGML does not standardize style or other processing methods for 26 information stored in SGML.</para></topic></section></result>
Locate all the topics referenced by a cross-reference anywhere in the report (all the "topic" elements whose "topicid" attribute value is the same as an "xrefid" attribute value of any "xref" element).
1 doc = XML.load('sgml.xml') 2 3 XML.result! { 4 doc.descendants(:xref) {|xref| 5 add! doc.descendants(:topic).find_all{|t| t[:topicid] == xref[:xrefid]} 6 } 7 }
<result> { for $id in doc("sgml.xml")//xref/@xrefid return doc("sgml.xml")//topic[@topicid = $id] } </result>
1 <result><topic topicid='top4'> 2 <title>Structure</title> 3 <para>At the heart of an SGML application is a file called the DTD, or 4 Document Type Definition. The DTD sets up the structure of a document, 5 much like a database schema describes the types of information it 6 handles.</para> 7 <para>A database schema also defines the relationships between the 8 various types of data. Similarly, a DTD specifies <emph>rules</emph> 9 to help ensure documents have a consistent, logical structure.</para></topic></result>
Locate the closest title preceding the cross-reference ("xref") element whose "xrefid" attribute is "top4" (the "title" element that would be touched last before this "xref" element when touching each element in document order).
1 doc = XML.load('sgml.xml') 2 3 XML.result! { 4 xref = doc.descendants(:xref).find{|xref| xref[:xrefid] == "top4"} 5 add! doc.range(nil,xref).descendants(:title)[-1] 6 }
<result> { let $x := doc("sgml.xml")//xref[@xrefid = "top4"], $t := doc("sgml.xml")//title[. << $x] return $t[last()] } </result>
1 <result><title>Content</title></result>
1 <?xml version="1.0" encoding="ISO-8859-1"?> 2 <!DOCTYPE company SYSTEM "company.dtd"> 3 <company> 4 <name>Foobar Corporation</name> 5 <ticker_symbol>FOO</ticker_symbol> 6 7 <description>Foobar Corporation is a maker of Foo(TM) and 8 Foobar(TM) products and a leading software company with a 300 9 Billion dollar revenue in 1999. It is located in Alaska. 10 </description> 11 12 <business_code>Software</business_code> 13 <partners> 14 <partner>YouNameItWeIntegrateIt.com</partner> 15 <partner>TheAppCompany Inc.</partner> 16 </partners> 17 <competitors> 18 <competitor>Gorilla Corporation</competitor> 19 </competitors> 20 </company>
1 <?xml version="1.0" encoding="ISO-8859-1"?> 2 <news> 3 <news_item> 4 <title> Gorilla Corporation acquires YouNameItWeIntegrateIt.com </title> 5 <content> 6 <par> Today, Gorilla Corporation announced that it will purchase 7 YouNameItWeIntegrateIt.com. The shares of 8 YouNameItWeIntegrateIt.com dropped $3.00 as a result of this 9 announcement. 10 </par> 11 12 <par> As a result of this acquisition, the CEO of 13 YouNameItWeIntegrateIt.com Bill Smarts resigned. He did not 14 announce what he will do next. Sources close to 15 YouNameItWeIntegrateIt.com hint that Bill Smarts might be 16 taking a position in Foobar Corporation. 17 </par> 18 19 <par>YouNameItWeIntegrateIt.com is a leading systems integrator 20 that enables <quote>brick and mortar</quote> companies to 21 have a presence on the web. 22 </par> 23 24 </content> 25 <date>1-20-2000</date> 26 <author>Mark Davis</author> 27 <news_agent>News Online</news_agent> 28 </news_item> 29 30 <news_item> 31 <title>Foobar Corporation releases its new line of Foo products 32 today</title> 33 <content> 34 <par> Foobar Corporation releases the 20.9 version of its Foo 35 products. The new version of Foo products solve known 36 performance problems which existed in 20.8 line and 37 increases the speed of Foo based products tenfold. It also 38 allows wireless clients to be connected to the Foobar 39 servers. 40 </par> 41 <par> The President of Foobar Corporation announced that they 42 were proud to release 20.9 version of Foo products and 43 they will upgrade existing customers <footnote>where 44 service agreements exist</footnote> 45 promptly. TheAppCompany Inc. immediately announced that it 46 will release the new version of its products to utilize 47 the 20.9 architecture within the next three months. 48 </par> 49 <figure> 50 <title>Presidents of Foobar Corporation and TheAppCompany 51 Inc. Shake Hands</title> <image source="handshake.jpg"/> 52 </figure> 53 </content> 54 <date>1-20-2000</date> 55 <news_agent>Foobar Corporation</news_agent> 56 </news_item> 57 58 <news_item> <title>Foobar Corporation is suing Gorilla Corporation for 59 patent infringement </title> 60 <content> 61 <par> In surprising developments today, Foobar Corporation 62 announced that it is suing Gorilla Corporation for patent 63 infringement. The patents that were mentioned as part of the 64 lawsuit are considered to be the basis of Foobar 65 Corporation's <quote>Wireless Foo</quote> line of products. 66 </par> 67 <par>The tension between Foobar and Gorilla Corporations has 68 been increasing ever since the Gorilla Corporation acquired 69 more than 40 engineers who have left Foobar Corporation, 70 TheAppCompany Inc. and YouNameItWeIntegrateIt.com over the 71 past 3 months. The engineers who have left the Foobar 72 corporation and its partners were rumored to be working on 73 the next generation of server products and applications which 74 will directly compete with Foobar's Foo 20.9 servers. Most of 75 the engineers have relocated to Hawaii where the Gorilla 76 Corporation's server development is located. 77 </par> 78 </content> 79 <date>1-20-2000</date> 80 <news_agent>Reliable News Corporation</news_agent> 81 </news_item> 82 </news>
Find the titles of all news items where the string "Foobar Corporation" appears in the title.
1 XML.load('string.xml').descendants(:news_item, :title).each{|t| 2 print t if t =~ /Foobar Corporation/ 3 }
doc("string.xml")//news_item/title[contains(., "Foobar Corporation")]
1 <title>Foobar Corporation releases its new line of Foo 2 products today</title> 3 <title>Foobar Corporation is suing Gorilla Corporation for patent 4 infringement </title>
Find news items where the Foobar Corporation and one or more of its partners are mentioned in the same paragraph and/or title. List each news item by its title and date.
1 partners = XML.load('company-data.xml').descendants(:partner).map{|p| p.text} 2 3 XML.load('string.xml').descendants(:news_item) {|item| 4 next unless (item.descendants(:title) + item.descendants(:par)).any?{|t| 5 t.text.include? "Foobar Corporation" and partners.any?{|p| t.text.include? p} 6 } 7 XML.news_item!(item.child(:title), item.child(:date)) 8 }
declare function local:partners($company as xs:string) as element()* { let $c := doc("company-data.xml")//company[name = $company] return $c//partner }; let $foobar_partners := local:partners("Foobar Corporation") for $item in doc("string.xml")//news_item where some $t in $item//title satisfies (contains($t/text(), "Foobar Corporation") and (some $partner in $foobar_partners satisfies contains($t/text(), $partner/text()))) or (some $par in $item//par satisfies (contains(string($par), "Foobar Corporation") and (some $partner in $foobar_partners satisfies contains(string($par), $partner/text())))) return <news_item> { $item/title } { $item/date } </news_item>
1 <news_item> 2 <title> Gorilla Corporation acquires YouNameItWeIntegrateIt.com </title> 3 <date>1-20-2000</date> 4 </news_item> 5 <news_item> 6 <title>Foobar Corporation releases its new line of Foo products today</title> 7 <date>1-20-2000</date> 8 </news_item> 9 <news_item> 10 <title>Foobar Corporation is suing Gorilla Corporation for patent 11 infringement </title> 12 <date>1-20-2000</date> 13 </news_item>
Find news items where a company and one of its partners is mentioned in the same news item and the news item is not authored by the company itself.
1 company_data = XML.load('company-data.xml') 2 partners = company_data.descendants(:partner).map{|p| p.text} 3 c = company_data[:@name] 4 5 XML.load('string.xml').descendants(:news_item) {|item| 6 next unless item.text.include? c 7 next unless partners.any?{|p| item.text.include? p} 8 next if item[:@news_agent] == c 9 print item 10 }
declare function local:partners($company as xs:string) as element()* { let $c := doc("company-data.xml")//company[name = $company] return $c//partner }; for $item in doc("string.xml")//news_item, $c in doc("company-data.xml")//company let $partners := local:partners($c/name) where contains(string($item), $c/name) and (some $p in $partners satisfies contains(string($item), $p) and $item/news_agent != $c/name) return $item
1 <news_item> 2 <title> Gorilla Corporation acquires YouNameItWeIntegrateIt.com </title> 3 <content> 4 <par> Today, Gorilla Corporation announced that it will purchase 5 YouNameItWeIntegrateIt.com. The shares of 6 YouNameItWeIntegrateIt.com dropped $3.00 as a result of this 7 announcement. 8 </par> 9 10 <par> As a result of this acquisition, the CEO of 11 YouNameItWeIntegrateIt.com Bill Smarts resigned. He did not 12 announce what he will do next. Sources close to 13 YouNameItWeIntegrateIt.com hint that Bill Smarts might be 14 taking a position in Foobar Corporation. 15 </par> 16 17 <par>YouNameItWeIntegrateIt.com is a leading systems integrator 18 that enables <quote>brick and mortar</quote> companies to 19 have a presence on the web. 20 </par> 21 22 </content> 23 <date>1-20-2000</date> 24 <author>Mark Davis</author> 25 <news_agent>News Online</news_agent> 26 </news_item> 27 <news_item> <title>Foobar Corporation is suing Gorilla Corporation for 28 patent infringement </title> 29 <content> 30 <par> In surprising developments today, Foobar Corporation 31 announced that it is suing Gorilla Corporation for patent 32 infringement. The patents that were mentioned as part of the 33 lawsuit are considered to be the basis of Foobar 34 Corporation's <quote>Wireless Foo</quote> line of products. 35 </par> 36 <par>The tension between Foobar and Gorilla Corporations has 37 been increasing ever since the Gorilla Corporation acquired 38 more than 40 engineers who have left Foobar Corporation, 39 TheAppCompany Inc. and YouNameItWeIntegrateIt.com over the 40 past 3 months. The engineers who have left the Foobar 41 corporation and its partners were rumored to be working on 42 the next generation of server products and applications which 43 will directly compete with Foobar's Foo 20.9 servers. Most of 44 the engineers have relocated to Hawaii where the Gorilla 45 Corporation's server development is located. 46 </par> 47 </content> 48 <date>1-20-2000</date> 49 <news_agent>Reliable News Corporation</news_agent> 50 </news_item>
For each news item that is relevant to the Gorilla Corporation, create an "item summary" element. The content of the item summary is the content of the title, date, and first paragraph of the news item, separated by periods. A news item is relevant if the name of the company is mentioned anywhere within the content of the news item.
1 XML.load('string.xml').descendants(:news_item) {|item| 2 next unless item =~ /Gorilla Corporation/ 3 XML.item_summary! { 4 add! item[:@title].strip 5 add! ". " 6 add! item[:@date] 7 add! ". " 8 add! item.descendants(:par)[0].text 9 } 10 }
for $item in doc("string.xml")//news_item where contains(string($item/content), "Gorilla Corporation") return <item_summary> { concat($item/title,". ") } { concat($item/date,". ") } { string(($item//par)[1]) } </item_summary>
1 <item_summary>Gorilla Corporation acquires 2 YouNameItWeIntegrateIt.com. 1-20-2000. Today, Gorilla Corporation 3 announced that it will purchase YouNameItWeIntegrateIt.com. The shares 4 of YouNameItWeIntegrateIt.com dropped $3.00 as a result of this 5 announcement.</item_summary> 6 7 <item_summary>Foobar Corporation is suing Gorilla Corporation for 8 patent infringement. 1-20-2000. In surprising developments today, 9 Foobar Corporation announced that it is suing Gorilla Corporation for 10 patent infringement. The patents that were mentioned as part of the 11 lawsuit are considered to be the basis of Foobar Corporation's 12 Wireless Foo line of products.</item_summary>
1 <?xml version="1.0"?> 2 <!DOCTYPE book SYSTEM "book.dtd"> 3 <book> 4 <title>Data on the Web</title> 5 <author>Serge Abiteboul</author> 6 <author>Peter Buneman</author> 7 <author>Dan Suciu</author> 8 <section id="intro" difficulty="easy" > 9 <title>Introduction</title> 10 <p>Text ... </p> 11 <section> 12 <title>Audience</title> 13 <p>Text ... </p> 14 </section> 15 <section> 16 <title>Web Data and the Two Cultures</title> 17 <p>Text ... </p> 18 <figure height="400" width="400"> 19 <title>Traditional client/server architecture</title> 20 <image source="csarch.gif"/> 21 </figure> 22 <p>Text ... </p> 23 </section> 24 </section> 25 <section id="syntax" difficulty="medium" > 26 <title>A Syntax For Data</title> 27 <p>Text ... </p> 28 <figure height="200" width="500"> 29 <title>Graph representations of structures</title> 30 <image source="graphs.gif"/> 31 </figure> 32 <p>Text ... </p> 33 <section> 34 <title>Base Types</title> 35 <p>Text ... </p> 36 </section> 37 <section> 38 <title>Representing Relational Databases</title> 39 <p>Text ... </p> 40 <figure height="250" width="400"> 41 <title>Examples of Relations</title> 42 <image source="relations.gif"/> 43 </figure> 44 </section> 45 <section> 46 <title>Representing Object Databases</title> 47 <p>Text ... </p> 48 </section> 49 </section> 50 </book>
Prepare a (nested) table of contents for Book1, listing all the sections and their titles. Preserve the original attributes of each <section> element, if any.
1 def local_toc(node) 2 node.children(:section).map{|c| 3 XML.section(c.attrs, c.child(:title), local_toc(c)) 4 } 5 end 6 7 XML.toc! { 8 add! local_toc(XML.load('book.xml')) 9 }
declare function local:toc($book-or-section as element()) as element()* { for $section in $book-or-section/section return <section> { $section/@* , $section/title , local:toc($section) } </section> }; <toc> { for $s in doc("book.xml")/book return local:toc($s) } </toc>
1 <toc> 2 <section id="intro" difficulty="easy"> 3 <title>Introduction</title> 4 <section> 5 <title>Audience</title> 6 </section> 7 <section> 8 <title>Web Data and the Two Cultures</title> 9 </section> 10 </section> 11 <section id="syntax" difficulty="medium"> 12 <title>A Syntax For Data</title> 13 <section> 14 <title>Base Types</title> 15 </section> 16 <section> 17 <title>Representing Relational Databases</title> 18 </section> 19 <section> 20 <title>Representing Object Databases</title> 21 </section> 22 </section> 23 </toc>
Prepare a (flat) figure list for Book1, listing all the figures and their titles. Preserve the original attributes of each <figure> element, if any.
1 XML.figlist! { 2 XML.load('book.xml').descendants(:figure) {|f| 3 figure!(f.attrs, f.children(:title)) 4 } 5 }
<figlist> { for $f in doc("book.xml")//figure return <figure> { $f/@* } { $f/title } </figure> } </figlist>
1 <figlist> 2 <figure height="400" width="400"> 3 <title>Traditional client/server architecture</title> 4 </figure> 5 <figure height="200" width="500"> 6 <title>Graph representations of structures</title> 7 </figure> 8 <figure height="250" width ="400"> 9 <title>Examples of Relations</title> 10 </figure> 11 </figlist>
How many sections are in Book1, and how many figures?
1 doc = XML.load('book.xml') 2 3 XML.section_count!(doc.descendants(:section).size) 4 XML.figure_count!(doc.descendants(:figure).size)
<section_count>{ count(doc("book.xml")//section) }</section_count>, <figure_count>{ count(doc("book.xml")//figure) }</figure_count>
1 <section_count>7</section_count> 2 <figure_count>3</figure_count>
How many top-level sections are in Book1?
1 XML.top_section_count!(XML.load('book.xml').children(:section).size)
<top_section_count> { count(doc("book.xml")/book/section) } </top_section_count>
1 <top_section_count>2</top_section_count>
Make a flat list of the section elements in Book1. In place of its original attributes, each section element should have two attributes, containing the title of the section and the number of figures immediately contained in the section.
1 XML.section_list! { 2 XML.load('book.xml').descendants(:section) {|s| 3 section!({ 4 :title => s[:@title], 5 :figcount => s.children(:figure).size, 6 }) 7 } 8 }
<section_list> { for $s in doc("book.xml")//section let $f := $s/figure return <section title="{ $s/title/text() }" figcount="{ count($f) }"/> } </section_list>
1 <section_list> 2 <section title="Introduction" figcount="0"/> 3 <section title="Audience" figcount="0"/> 4 <section title="Web Data and the Two Cultures" figcount="1"/> 5 <section title="A Syntax For Data" figcount="1"/> 6 <section title="Base Types" figcount="0"/> 7 <section title="Representing Relational Databases" figcount="1"/> 8 <section title="Representing Object Databases" figcount="0"/> 9 </section_list>
Make a nested list of the section elements in Book1, preserving their original attributes and hierarchy. Inside each section element, include the title of the section and an element that includes the number of figures immediately contained in the section.
1 def section_summary(s) 2 XML.section(s.attrs) { 3 add! s.child(:title) 4 figcount! s.children(:figure).size 5 add! s.children(:section).map{|c| section_summary(c)} 6 } 7 end 8 9 XML.toc! { 10 XML.load('book.xml').children(:section) {|s| 11 add! section_summary(s) 12 } 13 }
declare function local:section-summary($book-or-section as element()*) as element()* { for $section in $book-or-section return <section> { $section/@* } { $section/title } <figcount> { count($section/figure) } </figcount> { local:section-summary($section/section) } </section> }; <toc> { for $s in doc("book.xml")/book/section return local:section-summary($s) } </toc>
1 <toc> 2 <section id="intro" difficulty="easy"> 3 <title>Introduction</title> 4 <figcount>0</figcount> 5 <section> 6 <title>Audience</title> 7 <figcount>0</figcount> 8 </section> 9 <section> 10 <title>Web Data and the Two Cultures</title> 11 <figcount>1</figcount> 12 </section> 13 </section> 14 <section id="syntax" difficulty="medium"> 15 <title>A Syntax For Data</title> 16 <figcount>1</figcount> 17 <section> 18 <title>Base Types</title> 19 <figcount>0</figcount> 20 </section> 21 <section> 22 <title>Representing Relational Databases</title> 23 <figcount>1</figcount> 24 </section> 25 <section> 26 <title>Representing Object Databases</title> 27 <figcount>0</figcount> 28 </section> 29 </section> 30 </toc>
1 <bib> 2 <book year="1994"> 3 <title>TCP/IP Illustrated</title> 4 <author><last>Stevens</last><first>W.</first></author> 5 <publisher>Addison-Wesley</publisher> 6 <price>65.95</price> 7 </book> 8 9 <book year="1992"> 10 <title>Advanced Programming in the Unix environment</title> 11 <author><last>Stevens</last><first>W.</first></author> 12 <publisher>Addison-Wesley</publisher> 13 <price>65.95</price> 14 </book> 15 16 <book year="2000"> 17 <title>Data on the Web</title> 18 <author><last>Abiteboul</last><first>Serge</first></author> 19 <author><last>Buneman</last><first>Peter</first></author> 20 <author><last>Suciu</last><first>Dan</first></author> 21 <publisher>Morgan Kaufmann Publishers</publisher> 22 <price>39.95</price> 23 </book> 24 25 <book year="1999"> 26 <title>The Economics of Technology and Content for Digital TV</title> 27 <editor> 28 <last>Gerbarg</last><first>Darcy</first> 29 <affiliation>CITI</affiliation> 30 </editor> 31 <publisher>Kluwer Academic Publishers</publisher> 32 <price>129.95</price> 33 </book> 34 35 </bib>
1 <chapter> 2 <title>Data Model</title> 3 <section> 4 <title>Syntax For Data Model</title> 5 </section> 6 <section> 7 <title>XML</title> 8 <section> 9 <title>Basic Syntax</title> 10 </section> 11 <section> 12 <title>XML and Semistructured Data</title> 13 </section> 14 </section> 15 </chapter>
1 <prices> 2 <book> 3 <title>Advanced Programming in the Unix environment</title> 4 <source>bstore2.example.com</source> 5 <price>65.95</price> 6 </book> 7 <book> 8 <title>Advanced Programming in the Unix environment</title> 9 <source>bstore1.example.com</source> 10 <price>65.95</price> 11 </book> 12 <book> 13 <title>TCP/IP Illustrated</title> 14 <source>bstore2.example.com</source> 15 <price>65.95</price> 16 </book> 17 <book> 18 <title>TCP/IP Illustrated</title> 19 <source>bstore1.example.com</source> 20 <price>65.95</price> 21 </book> 22 <book> 23 <title>Data on the Web</title> 24 <source>bstore2.example.com</source> 25 <price>34.95</price> 26 </book> 27 <book> 28 <title>Data on the Web</title> 29 <source>bstore1.example.com</source> 30 <price>39.95</price> 31 </book> 32 </prices>
1 <reviews> 2 <entry> 3 <title>Data on the Web</title> 4 <price>34.95</price> 5 <review> 6 A very good discussion of semi-structured database 7 systems and XML. 8 </review> 9 </entry> 10 <entry> 11 <title>Advanced Programming in the Unix environment</title> 12 <price>65.95</price> 13 <review> 14 A clear and detailed discussion of UNIX programming. 15 </review> 16 </entry> 17 <entry> 18 <title>TCP/IP Illustrated</title> 19 <price>65.95</price> 20 <review> 21 One of the best books on TCP/IP. 22 </review> 23 </entry> 24 </reviews>
List books published by Addison-Wesley after 1991, including their year and title.
1 XML.bib! { 2 XML.load('bib.xml').children(:book) {|b| 3 if b[:@publisher] == "Addison-Wesley" and b[:year].to_i > 1991 4 book!({:year => b[:year]}, b.child(:title)) 5 end 6 } 7 }
<bib> { for $b in doc("http://bstore1.example.com/bib.xml")/bib/book where $b/publisher = "Addison-Wesley" and $b/@year > 1991 return <book year="{ $b/@year }"> { $b/title } </book> } </bib>
1 <bib> 2 <book year="1994"> 3 <title>TCP/IP Illustrated</title> 4 </book> 5 <book year="1992"> 6 <title>Advanced Programming in the Unix environment</title> 7 </book> 8 </bib>
Create a flat list of all the title-author pairs, with each pair enclosed in a "result" element.
1 XML.results! { 2 XML.load('bib.xml').children(:book) {|b| 3 t = b.child(:title) 4 b.children(:author) {|a| 5 result!(t,a) 6 } 7 } 8 }
<results> { for $b in doc("http://bstore1.example.com/bib.xml")/bib/book, $t in $b/title, $a in $b/author return <result> { $t } { $a } </result> } </results>
1 <results> 2 <result> 3 <title>TCP/IP Illustrated</title> 4 <author> 5 <last>Stevens</last> 6 <first>W.</first> 7 </author> 8 </result> 9 <result> 10 <title>Advanced Programming in the Unix environment</title> 11 <author> 12 <last>Stevens</last> 13 <first>W.</first> 14 </author> 15 </result> 16 <result> 17 <title>Data on the Web</title> 18 <author> 19 <last>Abiteboul</last> 20 <first>Serge</first> 21 </author> 22 </result> 23 <result> 24 <title>Data on the Web</title> 25 <author> 26 <last>Buneman</last> 27 <first>Peter</first> 28 </author> 29 </result> 30 <result> 31 <title>Data on the Web</title> 32 <author> 33 <last>Suciu</last> 34 <first>Dan</first> 35 </author> 36 </result> 37 </results>
For each book in the bibliography, list the title and authors, grouped inside a "result" element.
1 XML.results! { 2 XML.load('bib.xml').children(:book) {|b| 3 result!(b.children(:title), b.children(:author)) 4 } 5 }
<results> { for $b in doc("http://bstore1.example.com/bib.xml")/bib/book return <result> { $b/title } { $b/author } </result> } </results>
1 <results> 2 <result> 3 <title>TCP/IP Illustrated</title> 4 <author> 5 <last>Stevens</last> 6 <first>W.</first> 7 </author> 8 </result> 9 <result> 10 <title>Advanced Programming in the Unix environment</title> 11 <author> 12 <last>Stevens</last> 13 <first>W.</first> 14 </author> 15 </result> 16 <result> 17 <title>Data on the Web</title> 18 <author> 19 <last>Abiteboul</last> 20 <first>Serge</first> 21 </author> 22 <author> 23 <last>Buneman</last> 24 <first>Peter</first> 25 </author> 26 <author> 27 <last>Suciu</last> 28 <first>Dan</first> 29 </author> 30 </result> 31 <result> 32 <title>The Economics of Technology and Content for Digital TV</title> 33 </result> 34 </results>
For each author in the bibliography, list the author's name and the titles of all books by that author, grouped inside a "result" element.
1 XML.results! { 2 doc = XML.load('bib.xml') 3 a = doc.descendants(:author) 4 books = doc.children(:book) 5 6 a.map{|node| 7 [node[:@last], node[:@first]] 8 }.uniq.sort.each {|last, first| 9 result! { 10 author! { 11 last! last 12 first! first 13 } 14 books.each{|b| 15 next unless b.children(:author).any?{|ba| 16 ba[:@last] == last and ba[:@first] == first 17 } 18 add! b.children(:title) 19 } 20 } 21 } 22 }
<results> { let $a := doc("http://bstore1.example.com/bib/bib.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("http://bstore1.example.com/bib.xml")/bib/book where some $ba in $b/author satisfies ($ba/last = $last and $ba/first=$first) return $b/title } </result> } </results>
1 <results> 2 <result> 3 <author> 4 <last>Abiteboul</last> 5 <first>Serge</first> 6 </author> 7 <title>Data on the Web</title> 8 </result> 9 <result> 10 <author> 11 <last>Buneman</last> 12 <first>Peter</first> 13 </author> 14 <title>Data on the Web</title> 15 </result> 16 <result> 17 <author> 18 <last>Stevens</last> 19 <first>W.</first> 20 </author> 21 <title>TCP/IP Illustrated</title> 22 <title>Advanced Programming in the Unix environment</title> 23 </result> 24 <result> 25 <author> 26 <last>Suciu</last> 27 <first>Dan</first> 28 </author> 29 <title>Data on the Web</title> 30 </result> 31 </results>
For each book found at both bstore1.example.com and bstore2.example.com, list the title of the book and its price from each source.
1 xml!(:"books-with-prices") { 2 books = XML.load("bib.xml").descendants(:book) 3 entries = XML.load("reviews.xml").descendants(:entry) 4 books.each{|b| 5 entries.each{|a| 6 next unless a[:@title] == b[:@title] 7 xml!(:"book-with-prices") { 8 add! b.child(:title) 9 xml!(:"price-bstore2", a[:@price]) 10 xml!(:"price-bstore1", b[:@price]) 11 } 12 } 13 } 14 }
<books-with-prices> { for $b in doc("http://bstore1.example.com/bib.xml")//book, $a in doc("http://bstore2.example.com/reviews.xml")//entry where $b/title = $a/title return <book-with-prices> { $b/title } <price-bstore2>{ $a/price/text() }</price-bstore2> <price-bstore1>{ $b/price/text() }</price-bstore1> </book-with-prices> } </books-with-prices>
1 <books-with-prices> 2 <book-with-prices> 3 <title>TCP/IP Illustrated</title> 4 <price-bstore2>65.95</price-bstore2> 5 <price-bstore1>65.95</price-bstore1> 6 </book-with-prices> 7 <book-with-prices> 8 <title>Advanced Programming in the Unix environment</title> 9 <price-bstore2>65.95</price-bstore2> 10 <price-bstore1>65.95</price-bstore1> 11 </book-with-prices> 12 <book-with-prices> 13 <title>Data on the Web</title> 14 <price-bstore2>34.95</price-bstore2> 15 <price-bstore1>39.95</price-bstore1> 16 </book-with-prices> 17 </books-with-prices>
For each book that has at least one author, list the title and first two authors, and an empty "et-al" element if the book has additional authors.
1 XML.bib! { 2 XML.load('bib.xml').children(:book) {|b| 3 next unless b.children(:author).size > 0 4 book! { 5 add! b.children(:title) 6 authors = b.children(:author) 7 add! authors[0,2] 8 xml!(:"et-al") if authors.size > 2 9 } 10 } 11 }
<bib> { for $b in doc("http://bstore1.example.com/bib.xml")//book where count($b/author) > 0 return <book> { $b/title } { for $a in $b/author[position()<=2] return $a } { if (count($b/author) > 2) then <et-al/> else () } </book> } </bib>
1 <bib> 2 <book> 3 <title>TCP/IP Illustrated</title> 4 <author> 5 <last>Stevens</last> 6 <first>W.</first> 7 </author> 8 </book> 9 <book> 10 <title>Advanced Programming in the Unix environment</title> 11 <author> 12 <last>Stevens</last> 13 <first>W.</first> 14 </author> 15 </book> 16 <book> 17 <title>Data on the Web</title> 18 <author> 19 <last>Abiteboul</last> 20 <first>Serge</first> 21 </author> 22 <author> 23 <last>Buneman</last> 24 <first>Peter</first> 25 </author> 26 <et-al/> 27 </book> 28 </bib>
List the titles and years of all books published by Addison-Wesley after 1991, in alphabetic order.
1 XML.bib! { 2 XML.load('bib.xml').children(:book).find_all{|b| 3 b[:@publisher] == "Addison-Wesley" and 4 b[:year].to_i > 1991 5 }.sort_by{|b| b[:@title] }.each {|b| 6 book!({:year => b[:year]}, b.child(:title)) 7 } 8 }
<bib> { for $b in doc("http://bstore1.example.com/bib.xml")//book where $b/publisher = "Addison-Wesley" and $b/@year > 1991 order by $b/title return <book> { $b/@year } { $b/title } </book> } </bib>
1 <bib> 2 <book year="1992"> 3 <title>Advanced Programming in the Unix environment</title> 4 </book> 5 <book year="1994"> 6 <title>TCP/IP Illustrated</title> 7 </book> 8 </bib>
Find books in which the name of some element ends with the string "or" and the same element contains the string "Suciu" somewhere in its content. For each such book, return the title and the qualifying element.
1 XML.load('bib.xml').children(:book) {|b| 2 b.descendants {|e| 3 if e.is_a? XML and e =~ /Suciu/ and e.name.to_s =~ /or$/ 4 XML.book!(b.child(:title), e) 5 end 6 } 7 }
for $b in doc("http://bstore1.example.com/bib.xml")//book let $e := $b/*[contains(string(.), "Suciu") and ends-with(local-name(.), "or")] where exists($e) return <book> { $b/title } { $e } </book>
1 <book> 2 <title>Data on the Web</title> 3 <author> 4 <last>Suciu</last> 5 <first>Dan</first> 6 </author> 7 </book>
In the document "books.xml", find all section or chapter titles that contain the word "XML", regardless of the level of nesting.
1 XML.results! { 2 XML.load('books.xml').descendants {|d| 3 if d.is_a? XML and (d.name == :chapter or d.name == :section) 4 t = d.child(:title) 5 add! t if t =~ /XML/ 6 end 7 } 8 }
<results> { for $t in doc("books.xml")//(chapter | section)/title where contains($t/text(), "XML") return $t } </results>
1 <results> 2 <title>XML</title> 3 <title>XML and Semistructured Data</title> 4 </results>
In the document "prices.xml", find the minimum price for each book, in the form of a "minprice" element with the book title as its title attribute.
1 XML.results! { 2 doc = XML.load('prices.xml') 3 doc.children(:book).children(:title).map{|node| node.text}.uniq.each{|title| 4 minprice!({:title => title}) { 5 price! { 6 text! doc.children(:book).find_all{|book| 7 book[:@title] == title 8 }.map{|book| 9 book[:@price].to_f 10 }.min 11 } 12 } 13 } 14 }
<results> { let $doc := doc("prices.xml") for $t in distinct-values($doc//book/title) let $p := $doc//book[title = $t]/price return <minprice title="{ $t }"> <price>{ min($p) }</price> </minprice> } </results>
1 <results> 2 <minprice title="Advanced Programming in the Unix environment"> 3 <price>65.95</price> 4 </minprice> 5 <minprice title="TCP/IP Illustrated"> 6 <price>65.95</price> 7 </minprice> 8 <minprice title="Data on the Web"> 9 <price>34.95</price> 10 </minprice> 11 </results>
For each book with an author, return the book with its title and authors. For each book with an editor, return a reference with the book title and the editor's affiliation.
1 XML.bib! { 2 doc = XML.load('bib.xml') 3 4 doc.children(:book) {|b| 5 if b.children(:author).size != 0 6 book!(b.children(:title), b.children(:author)) 7 end 8 } 9 10 doc.children(:book) {|b| 11 if b.children(:editor).size != 0 12 reference!(b.children(:title), b.children(:editor).children(:affiliation)) 13 end 14 } 15 }
<bib> { for $b in doc("http://bstore1.example.com/bib.xml")//book[author] return <book> { $b/title } { $b/author } </book> } { for $b in doc("http://bstore1.example.com/bib.xml")//book[editor] return <reference> { $b/title } {$b/editor/affiliation} </reference> } </bib>
1 <bib> 2 <book> 3 <title>TCP/IP Illustrated</title> 4 <author> 5 <last>Stevens</last> 6 <first>W.</first> 7 </author> 8 </book> 9 <book> 10 <title>Advanced Programming in the Unix environment</title> 11 <author> 12 <last>Stevens</last> 13 <first>W.</first> 14 </author> 15 </book> 16 <book> 17 <title>Data on the Web</title> 18 <author> 19 <last>Abiteboul</last> 20 <first>Serge</first> 21 </author> 22 <author> 23 <last>Buneman</last> 24 <first>Peter</first> 25 </author> 26 <author> 27 <last>Suciu</last> 28 <first>Dan</first> 29 </author> 30 </book> 31 <reference> 32 <title>The Economics of Technology and Content for Digital TV</title> 33 <affiliation>CITI</affiliation> 34 </reference> 35 </bib>
Find pairs of books that have different titles but the same set of authors (possibly in a different order).
1 XML.bib! { 2 books = XML.load('bib.xml').children(:book) 3 books.each_with_index{|book1, i| 4 aut1 = book1.children(:author).map{|a| [a[:@last], a[:@first]]}.sort 5 6 books.each_with_index{|book2, j| 7 next unless i < j and book1[:@title] != book2[:@title] 8 aut2 = book2.children(:author).map{|a| [a[:@last], a[:@first]]}.sort 9 10 xml!(:"book-pair", book1.child(:title), book2.child(:title)) if aut1 == aut2 11 } 12 } 13 }
<bib> { for $book1 in doc("http://bstore1.example.com/bib.xml")//book, $book2 in doc("http://bstore1.example.com/bib.xml")//book let $aut1 := for $a in $book1/author order by $a/last, $a/first return $a let $aut2 := for $a in $book2/author order by $a/last, $a/first return $a where $book1 << $book2 and not($book1/title = $book2/title) and deep-equal($aut1, $aut2) return <book-pair> { $book1/title } { $book2/title } </book-pair> } </bib>
1 <bib> 2 <book-pair> 3 <title>TCP/IP Illustrated</title> 4 <title>Advanced Programming in the Unix environment</title> 5 </book-pair> 6 </bib>