#!/usr/bin/env ruby # This code comes from http://ruby-it.org/pages/Roxi # Check the page for copyright notice and explanations # creazione di un elemento XElement.new('node') # creazione di un elemento contenente del testo XElement.new('node', XText.new('text')) # i metodi di manipolazione del dom sono abbastanza "smart" da # riconoscere i tipi di dati passati come parametri attuali e quindi # comportarsi di conseguenza XElement.new('node', 'text') # creazione di un documento un po' piu' complesso XDocument.new( XElement.new('root', XAttribute.new('attribute_1', 'value'), XAttribute.new('attribute_2', 'value'), XInstruction.new('php', 'phpinfo();') XElement.new('child', XNamespace.new('prefix', '/some/url'), XAttribute.new('attribute', 'value'), XElement.new('child', XAttribute.new('attribute', 'value') XElement.new('child', XComment.new('some comment'), ) ) ), XText.new('some text'), ) ) # esempi di utilizzo di XPath # il codice seguente calcola il prezzo totale di un ordine total = XDocument.open(@order) do | doc | doc.xpath('//item').inject(0) do | total, item | price = item.child('price').to_n quantity = item.child('quantity').to_n total += price * quantity end end # in maniera piu' compatta, sfruttando di piu' xpath total = XDocument.open(@order) do | doc | doc.xpath('//item').inject(0) do | total, item | total += item.xpath('price * quantity') end end # ancora piu' compatto, sfruttando delle estensioni non standard (mul) total = XDocument.open(@order).xpath('sum(mul(//item/price, //item/quantity))') # esempi di utilizzo di XUpdate (esempio originale e relativa traduzione) # # # Lennox # # doc = XDocument.string(@xml).update do select('/addresses/address[@id=1]/name/last') do | node | node.insert_before(XElement.new('middle', 'Lennox')) end end # # # # # # doc = XDocument.string(@xml).update do select('/addresses/address[@id=1]') do | node | node.child('country').insert_after(node.child('state').clone) end end # # # doc = XDocument.string(@xml).update do remove('/addresses/address[@id=1]/phone') end # alcuni esempi di utilizzo di XQuery (esempio originale e traduzione) # element = XElement.new('ul', XQuery.from(XDocument.open(@books).xpath('/bookstore/book/title')) do order_by { | title | title.value } select { | title | XElement.new('li', title) } end ) # supporto anche delle features non standard come la group_by (anche # se un po' macchinosa), e la filter dove e' possibile manipolare # tutto il result set attuale, in questo caso viene utilizzato per # limitare il numero di risultati XQuery.from(nodeset) do order_by(:descending) { | selection | selection.attribute('take').to_f } filter { | selections | selections[1..15] } select { | selection | puts selection.attribute('take').value } end # in piu' con opportune estensioni di xpath (in questo caso le # funzioni distinct-values e min) si riescono ad eseguire query # di questo tipo # # { # let $doc := doc("prices.xml") # for $t in distinct-values($doc//book/title) # let $p := $doc//book[title = $t]/price # return # # { min($p) } # # } # doc = XDocument.open(@prices) XElement.new('result', XQuery.from(doc.xpath('distinct-values(//book/title)')) do select do | title | minprice = doc.xpath("min(//book[title = '#{title}']/price)") XElement.new('minprice', XAttribute.new('title', title), XElement.new('price', minprice) ) end end ) ) # esempio di Binding # Definiamo per ogni attributo della classe News # l'espressione XPath che una volta valutata costituirĂ  # il valore dell'attributo stesso class News extend XBind xattribute :title => 'only(strings(*[@class = "title"]))' xattribute :insert_date => 'only(dates(*[@class = "insert_date"]))' xattribute :expire_date => 'only(dates(*[@class = "expire_date"]))' xattribute :text => 'normalize-space(only(strings(*[@class = "text"])))' end # supponiamo di avere un xml di questo tipo # # # XPUG NEWS # # #
# First News # 20060404 # 20060414 #
# First News Text #
#
#
# Second News # 20060403 # 20060413 #
# Second News Text #
#
#
# Third News # 20060402 # 20060412 #
# Third News Text #
#
# # # per ogni news presente nella pagina eseguiamo dei test today = Date.today XDocument.open('.html').xpath('//*[@class = "news"]').each do | news_dom | news = News.new(news_dom) assert today <= news.expire_date, "'#{news.title}' should be expired at #{today}" end # news = News.new(news_dom) # istanzia News # valorizza gli attributi dell'oggetto valutando le espressioni xpath su news_dom # crea i metodi di accesso agli attributi