Jacki
March 30, 2015, 3:00pm
1
Hej
Mam plik xml w formacie:
<?xml version="1.0" encoding="UTF-8"?>
<teryt>
<catalog name="ULIC" type="all">
<row>
<col name="SYM_UL">18316</col>
<col name="CECHA">ul.</col>
<col name="NAZWA_1">Radomska</col>
</row>
<row>
<col name="SYM_UL">19002</col>
<col name="CECHA">ul.</col>
<col name="NAZWA_1">Różanostocka</col>
<col name="NAZWA_2"/>
</row>
itd.Jest to plik z bazy TERYT - dla danej miejscowości. Potrzebuję wyciągnąć z niego symbol ulicy mając jej nazwę. Chcę to zrobic elegandzko. Ale moja wiedza z nokogiri kończy się na
content.xpath(’//row’).each do |row|
i tu mam oddzielnie każdy
Mogę to zrobić ręcznie, ale myślę, że da się po prostu jakoś to zrobić tym gemem.
cube
March 30, 2015, 3:57pm
2
Nokogiri::XML(xml).at('row:has(col[name="NAZWA_1"][text()="Radomska"]) col[name="SYM_UL"]').text
wafcio
March 30, 2015, 6:14pm
4
Można się bawić nokogiri, czasami jest to bardziej użyteczne niż inne rozwiązania. W twoim rozwiązaniu, może multi_xml by się nadało.
mercer
March 31, 2015, 7:16pm
5
Dołożę swoje pytanie do tego tematu - powyższy kod jak i zaproponowany dalej wymaga jakiejś zmiennej gdzie będzie załadowany cały plik xml. Czasem jest on wielki, więc zdarzyło mi się już, że brakło pamięci.
Co zrobić by xml był odczytywany po jednym tagu “row”?
W samym nokogiri możesz użyć albo pełnego sax parsera
http://www.rubydoc.info/github/sparklemotion/nokogiri/Nokogiri/XML/SAX/Parser
albo dużo lżejszego readera
http://www.rubydoc.info/github/sparklemotion/nokogiri/Nokogiri/XML/Reader
Tej drugiej opcji używałem, iterujesz po każdym tagu (przy czym dostajesz i otwierający i zamykający) i jest to dość proste i szybkie.
Niestety też “dotknął” mnie TERYT.
Chcę pliki - na początek TERC.xml - załadować do bazy. Napisałem taki fragment:
require 'nokogiri'
file = File.open(File.join("db/seeds/files", "TERC.xml"))
doc = Nokogiri::XML(file)
doc.xpath('//row').each do |row_element|
puts row_element
puts row_element.text
end
i dostaję dla poszczególnych wierszy coś takiego:
<row>
<col name="WOJ">32</col>
<col name="POW">63</col>
<col name="GMI">01</col>
<col name="RODZ">1</col>
<col name="NAZWA">Świnoujście</col>
<col name="NAZDOD">gmina miejska</col>
<col name="STAN_NA">2016-01-01</col>
</row>
32
63
01
1
Świnoujście
gmina miejska
2016-01-01
Chciałbym do swojej bazy wprowadzać te wartości z tej pętli jakoś tak
MyTable.new()
MyTable.woj = …
MyTable.pow = …
…
MyTable.save
ale nie potrafię wybrać atrybutu z czegoś takiego "<col name="WOJ">32</col>"
, gdyż za słabo znam Nokogiri, a przykłady tam zamieszczone przeważnie odnoszą się do takich wpisów <woj>32</woj>"
Ktoś może mi pomóc?
Jacki
March 10, 2016, 12:23pm
8
Ja potrzebowałem Do miejscowości zrobić spis nazw ulic z kodami ulic itp. Mam to zrobione tak:
City.all.each do |c|
next unless File.exist?("ulic/ulic_#{c.name.gsub(/ /, '_')}.xml")
file = File.open("ulic/ulic_#{c.name.gsub(/ /, '_')}.xml")
content = Nokogiri::XML(file)
content.search("row:has(col[name=\"NAZWA\"][text()=\"#{c.name}\"])").each do |t|
name_1 = t.at("col[name=\"NAZWA_1\"]").text
name_2 = t.at("col[name=\"NAZWA_2\"]").text
property = t.at("col[name=\"CECHA\"]").text
ulic = t.at("col[name=\"SYM_UL\"]").text
(...)
end
end
Gdzie jednym z miast była ‘Sokółka’ (City.name) a jeden row z pliku xml to:
<row>
<col name="WOJ">20</col>
<col name="NAZWA_WOJ">PODLASKIE</col>
<col name="POW">11</col>
<col name="NAZWA_POW">sokólski</col>
<col name="GMI">08</col>
<col name="NAZWA_GMN">Sokółka</col>
<col name="RODZ_GMN">4</col>
<col name="NAZWA_RODZ_GMN">miasto w gminie miejsko-wiejskiej</col>
<col name="NAZWA">Sokółka</col>
<col name="SYM">0923443</col>
<col name="SYMPOD">0923443</col>
<col name="KOD_RM">96</col>
<col name="NAZWA_RM">miasto </col>
<col name="SYM_UL">25107</col>
<col name="CECHA">ul.</col>
<col name="NAZWA_1">Wyszyńskiego</col>
<col name="NAZWA_2">kard. Stefana </col>
</row>
Myślę, że sobie poradzisz.