2017-05-08 5 views
-1

일반적으로 Nokogiri를 XML 파서로 사용합니다. 어떻게 필터링 할Ruby의 날짜 범위로 XML 요소를 필터링하는 방법

<aldo_nova album="aldo nova"> 
    <release_date value="19820401"/> 
</aldo_nova> 
<engligh_beat album="I Just Can't Stop It"/> 
    <release_date value="19800501"/> 
</engligh_beat> 

을 :

<albums> 
    <aldo_nova album="aldo nova"> 
     <release_date value="19820401"/> 
    </aldo_nova> 
    <classix_nouveaux album="Night People"/> 
     <release_date value="19820501"/> 
    </classix_nouveaux> 
    <engligh_beat album="I Just Can't Stop It"/> 
     <release_date value="19800501"/> 
    </engligh_beat> 
</albums> 

내가 1980년 1월 1일과 1982년 4월 15일 사이에 발매 된 모든 앨범을 얻으려면 :

나는 다음과 같은 XML을/release_date 범위로 XML을 쿼리 하시겠습니까?

+0

링크 된 페이지 "[mcve]"및 "[스택 오버플로 사용자에 대한 연구 노력의 정도는 얼마나 될까요?] (http://meta.stackoverflow.com/questions/261592)를 읽고"[ask] ". 우리는 당신의 노력에 대한 증거를보고 싶습니다. 너 무슨 짓을 한거야? 수색하고 아무것도 찾지 못했습니까? 물건을 찾았지만 도움이되지 않았습니까? 코드 작성을 시도 했습니까? 그렇지 않다면, 왜? 그렇다면 무엇을 시도했는지 그리고 왜 작동하지 않는지 보여주는 가장 작은 코드 예제는 무엇입니까? 그것 없이는 당신이 시도하지 않았고 우리가 당신을 위해 그것을 쓰길 원했던 것처럼 보입니다. –

답변

0

XML의 형식이 잘못되었습니다. 구문 분석 한 후, 여기 노코 기리 그것에 대해 말해야하는 내용은 다음과 같습니다

<classix_nouveaux album="Night People"/> 

<engligh_beat album="I Just Can't Stop It"/> 

이 종료되어 있기 때문이다

doc.errors 
# => [#<Nokogiri::XML::SyntaxError: Opening and ending tag mismatch: albums line 1 and classix_nouveaux>, 
#  #<Nokogiri::XML::SyntaxError: Extra content at the end of the document>] 

합니다. 대신 그들은해야합니다 :

<classix_nouveaux album="Night People"> 

<engligh_beat album="I Just Can't Stop It"> 

당신은 정확히 일치, 또는 하위 문자열 일치를 찾기 위해 CSS 또는 XPath를 선택기를 사용할 수 있지만, 어느 CSS 또는 XPath는 날짜의 "범위"를 이해 없으며이 날짜가 무엇인지 생각을해야합니까, 그래서 당신은 모든 노드를 추출이 경우 Date 객체 또는 정수로 날짜 값을 변환해야 할 것, 다음 범위에 비교 :

date_range = 19800501..19820401 
selected_albums = doc.search('//release_date').select { |rd| date_range.include?(rd['value'].to_i) }.map { |rd| rd.parent } 

selected_albums.map(&:to_xml) 
# => ["<aldo_nova album=\"aldo nova\">\n" + 
# " <release_date value=\"19820401\"/>\n" + 
# "</aldo_nova>", 
#  "<engligh_beat album=\"I Just Can't Stop It\">\n" + 
# " <release_date value=\"19800501\"/>\n" + 
# "</engligh_beat>"] 

나는 y라고 생각한다. 우리는 앨범이되어야 할 것에 대한 다양한 태그 이름을 가지고 있기 때문에 우리의 XML은 잘못 설계되었습니다. <album><albums>의 하위이어야합니다. 나는이 같은 것을 권 해드립니다 :

<collection> 
    <albums> 
    <album band="aldo nova" title="aldo nova" release_date="19820401"/> 
    <album band="classix nouveaux" title="Night People" release_date="19820501"/> 
    <album band="english beat" title="I Just Can't Stop It" release_date="19800501"/> 
    </albums> 
</collection> 

는 XML 표준 형태로되면, 탐색 용이하게 검색 :

require 'nokogiri' 

doc = Nokogiri::XML(<<EOT) 
<collection> 
    <albums> 
    <album band="aldo nova" title="aldo nova" release_date="19820401"/> 
    <album band="classix nouveaux" title="Night People" release_date="19820501"/> 
    <album band="english beat" title="I Just Can't Stop It" release_date="19800501"/> 
    </albums> 
</collection> 
EOT 

doc.search('album').last['title'] # => "I Just Can't Stop It" 

band = 'aldo nova' 
doc.search("//album[@band='#{band}']").map { |a| a['title'] } # => ["aldo nova"] 

하고 아니기 때문에 날짜 검색은 더 간단하게 노드의 부모를 찾을 필요 :

date_range = 19800501..19820401 
selected_albums = doc.search('album').select { |a| date_range.include?(a['release_date'].to_i) } 
selected_albums.map(&:to_xml) 
# => ["<album band=\"aldo nova\" title=\"aldo nova\" release_date=\"19820401\"/>", 
#  "<album band=\"english beat\" title=\"I Just Can't Stop It\" release_date=\"19800501\"/>"] 

나는 그것이 데이터가 LOGI를 표시하지 않은 경우 코너에 자신을 페인트 쉽게로 XML 자체에 대한 몇 가지 튜토리얼을 읽고 권하고 싶습니다 캘리와 올바르게.