…Parsuję, ale miałem nadzieję, że jest jakieś magiczne xpath("./*[local-name()='parametr']")… które da mi takie unikalne wartości.
Nie ma? Trudno. Będę iterował, wrzucał do tablicy i później uniq zastosuję.
gwoli ścisłości - nie zawsze. To prawda, jeśli chodzi o parsery, które budują “drzewo” z parsowanego dokumentu. Ale jeśli parsowany dokument jest duży, to czasem warto skorzystać z tzw. “streaming parsers”, które emitują “zdarzenia” odpowiadające odwiedzanym elementom dokumentu - taki trochę Visitor Pattern.
Komplikacją jest to, że trzeba samu zarządzać “kontekstem” (w tym przypadku: jeśli dostaniemy powiadomienie, że odwiedzamy własnie element “tytul”, to musimy w tym momencie moc stwierdzic, ze biezacym rodzicem obecnego elementu jest “parametr”, czyli musielismy juz wczesniej rowniez obsluzyc wizyte elementu “parametr” - ale tylko tych 2ch w tym konkretnym przypadku). I bedzie to dzialac szybko nawet dla baaardzo duzych dokumentow (a nawet pewnie dla nieskonczonego strumienia XML-a)
Przykład gemu który daje możliwość takiego parsowania:
To może, jak kolega wyżej radził, strumieniem? Nokogiri może również tak (przydaje się dla dużych plików):
require 'set'
require 'nokogiri'
titles = Set.new
Nokogiri::XML::Reader(File.open("data.xml")).each do |node|
if node.name == 'parametr' && node.node_type == Nokogiri::XML::Reader::TYPE_ELEMENT
title = Nokogiri::XML(node.inner_xml).at('/tytul').text
titles.add title unless titles.include? title
end
end
puts titles.to_a.join(",")