Ruby/XML/XPath
Материал из Wiki.crossplatform.ru
Count how many fish are inside the large fish.
xml = %{ <aquarium> <fish color="blue" size="small" /> <fish color="orange" size="large"> <fish color="green" size="small"> <fish color="red" size="tiny" /> </fish> </fish> <decoration type="castle" style="gaudy"> <algae color="green" /> </decoration> </aquarium>} require "rexml/document" doc = REXML::Document.new xml p REXML::XPath.first(doc, "count(//fish[@size="large"][1]//*fish)")
each loop on element
xml = %{ <aquarium> <fish color="blue" size="small" /> <fish color="orange" size="large"> <fish color="green" size="small"> <fish color="red" size="tiny" /> </fish> </fish> <decoration type="castle" style="gaudy"> <algae color="green" /> </decoration> </aquarium>} require "rexml/document" doc = REXML::Document.new xml p doc.elements.each("//fish") { |f| puts f.attribute("color") }
Find the color attributes of all small fish.
xml = %{ <aquarium> <fish color="blue" size="small" /> <fish color="orange" size="large"> <fish color="green" size="small"> <fish color="red" size="tiny" /> </fish> </fish> <decoration type="castle" style="gaudy"> <algae color="green" /> </decoration> </aquarium>} require "rexml/document" doc = REXML::Document.new xml p REXML::XPath.match(doc, "//fish[@size="small"]/@color")
Find the second green element.
xml = %{ <aquarium> <fish color="blue" size="small" /> <fish color="orange" size="large"> <fish color="green" size="small"> <fish color="red" size="tiny" /> </fish> </fish> <decoration type="castle" style="gaudy"> <algae color="green" /> </decoration> </aquarium>} require "rexml/document" doc = REXML::Document.new xml p REXML::XPath.match(doc, "//[@color="green"]")[1]
Get the first element and first child
xml = %{ <aquarium> <fish color="blue" size="small" /> <fish color="orange" size="large"> <fish color="green" size="small"> <fish color="red" size="tiny" /> </fish> </fish> <decoration type="castle" style="gaudy"> <algae color="green" /> </decoration> </aquarium>} require "rexml/document" doc = REXML::Document.new xml doc.elements[1] # => <aquarium> ... </> doc.children[0] # => <aquarium> ... </>
Get XPath from node
xml = %{ <aquarium> <fish color="blue" size="small" /> <fish color="orange" size="large"> <fish color="green" size="small"> <fish color="red" size="tiny" /> </fish> </fish> <decoration type="castle" style="gaudy"> <algae color="green" /> </decoration> </aquarium>} require "rexml/document" doc = REXML::Document.new xml p red_fish = doc.children[0] p red_fish.xpath p REXML::XPath.first(doc, red_fish.xpath)
Navigating a Document with XPath
xml = %{ <aquarium> <fish color="blue" size="small" /> <fish color="orange" size="large"> <fish color="green" size="small"> <fish color="red" size="tiny" /> </fish> </fish> <decoration type="castle" style="gaudy"> <algae color="green" /> </decoration> </aquarium>} require "rexml/document" doc = REXML::Document.new xml REXML::XPath.first(doc, "//fish") # => <fish size="small" color="blue"/>
Pass xml node to a method
xml = %{ <aquarium> <fish color="blue" size="small" /> <fish color="orange" size="large"> <fish color="green" size="small"> <fish color="red" size="tiny" /> </fish> </fish> <decoration type="castle" style="gaudy"> <algae color="green" /> </decoration> </aquarium>} require "rexml/document" doc = REXML::Document.new xml def describe(fish) "#{fish.attribute("size")} #{fish.attribute("color")} fish" end REXML::XPath.each(doc, "//fish/fish") do |fish| puts "#{describe(fish.parent)} #{describe(fish)}." end
REXML::XPath.match(doc, "//[@color="green"]")
xml = %{ <aquarium> <fish color="blue" size="small" /> <fish color="orange" size="large"> <fish color="green" size="small"> <fish color="red" size="tiny" /> </fish> </fish> <decoration type="castle" style="gaudy"> <algae color="green" /> </decoration> </aquarium>} require "rexml/document" doc = REXML::Document.new xml REXML::XPath.match(doc, "//[@color="green"]") # => [<fish size="small" color="green"> ... </>, <algae color="green"/>]
Search element by XPath
xml = %{ <aquarium> <fish color="blue" size="small" /> <fish color="orange" size="large"> <fish color="green" size="small"> <fish color="red" size="tiny" /> </fish> </fish> <decoration type="castle" style="gaudy"> <algae color="green" /> </decoration> </aquarium>} require "rexml/document" doc = REXML::Document.new xml p doc.elements["//fish"] # => <fish size="small" color="blue"/>