2016-10-01 2 views
5

마지막으로 조상 노드의 참조 변수에 따라 Nokogiri를 사용하여 여러 노드를 얻는 솔루션을 찾고있었습니다.변수 내에서 Nokogiri와 상위 조상 노드를 사용하여 다중 노드 선택

내가 필요한 것 : 실제로 "세그먼트"노드의 모든 "ID"를 수집 중입니다. 그런 다음 "세그먼트"노드를 사용하여 모든 후속 "자원"을 수집하려고합니다. "Resource"를 수집하기 위해 "Id"를 변수로 설정하려고합니다. 순간 모든 "SegmentId"의 모든 수집 "에서

A = 48000.0 
B = 240000.0 
C = 0.0 
D = 240000.0 

Some functions to calculate an average on the resources. 

puts all_arry 

A = 5.0 
B = 5.0 
C = 5.0 
D = 5.0 
A = 5.0 
B = 5.0 
C = 5.0 
D = 5.0 


=8 values -> only 4 values existing for the exact loop (2 average values per Segment) 

:

<CPL> 
    <SegmL> 
    <Segment> 
     <Id>UUID</Id> #UUID as a variable 
     <Name>name_01</Name> 
     <SeqL> 
      <ImageSequence> 
       <Id>UUID</Id> 
       <Track>UUID</Track> 
        <ResourceList> 
         <Resource> #depending on SegmentId 
          <A>aaa</A> 
          <B>bbb</B> 
          <C>ccc</C> 
          <D>ddd</D> 
         </Resource> 
        </ResourceList> 
      </ImageSequence> 
      <AudioSequence> 
       <Id>UUID</Id> 
       <Track>UUID</Track> 
        <ResourceList> 
         <Resource> 
          <A>aaa</A> 
          <B>bbb</B> 
          <C>ccc</C> 
          <D>ddd</D> 
         </Resource> 
        </ResourceList> 
      </AudioSequence> 
     </SequL> 
    </Segment> 
    <Segment> 
     <Id>UUIDa</Id> 
     <Name>name_02</Name> 
     <SequL> 
      <ImageSequence> 
       <Id>UUID</Id> 
       <Track>UUID</Track> 
        <ResourceList> 
         <Resource> 
          <A>aaa</A> 
          <B>bbb</B> 
          <C>ccc</C> 
          <D>ddd</D> 
         </Resource> 
        </ResourceList> 
      </ImageSequence> 
      <AudioSequence> 
       <Id>UUID</Id> 
       <Track>UUID</Track> 
        <ResourceList> 
         <Resource> 
          <A>aaa</A> 
          <B>bbb</B> 
          <C>ccc</C> 
          <D>ddd</D> 
         </Resource> 
        </ResourceList> 
      </AudioSequence> 
     </SequL> 
    </Segment> 
    </SegmL> 
</CPL> 

모든 자원 데이터는 각 A = Resource.css("A").text.gsub(/\n/,"")

#first each do 
cpls.each_with_index do |(cpl_uuid, mycpl), index| 
cpl_filename = mycpl 
cpl_file = File.open("#{resource_uri}/#{cpl_filename}") 
cpl = Nokogiri::XML(cpl_file).remove_namespaces! 

#get UUID for UUID checks 
cpl_uuid = cpl.css("Id").first.text.gsub(/\n/,"") 
cpl_root_edit_rate = cpl.css("EditRate").first.text.gsub(/\s+/, "\/") 

    #second each do 
    cpl.css("Segment").each do |s| # loop segment 
     cpl_segment_list_uuid = s.css("Id").first.text.gsub(/\n/,"") #uuid of segment list 

     #third each do 
     cpl.css("Resource").each do |f| #loop resources 
      cpl_A = f.css("A").text.gsub(/\n/,"") # uuid of A 
      cpl_B = f.css("B").text.gsub(/\n/,"") # uuid of B 
     end #third 
    end #second 
end #first 

내 표현으로 수집하는 것은 나에게 배열에 저장이 정보를 제공합니다 리소스 "

다음 리소스를 정확히 어떻게 할당 할 수 있습니까? 세그먼트 ID를 변수로 사용 하시겠습니까? ...

이 코드를 사용했지만, 루프 때문에 "세그먼트"의 "ID"를 각각 "자원", "A", "B"betwerrn 좀 더 노드의 생각, 비어 :

if cpl.at("Segment/Id:contains(\"#{cpl_segment_list_uuid}\")") 
    cpl.css("Resource").each do |f| 
     #collecting resources here for each segmet 
    end 
end 

모든 노드는 내 문제를 도와 줄 수 있습니다 NO attribues, IDS, 클래스 등

이 없습니다. 우선, 정치적으로 당신의지지에 감사드립니다!

내가 또한 자원에 "각 수행"에 대한 다음과 같은 식으로 코드를 실행 않았다 10/07/16

UPDATE :

expression = "/SegmetList/Segment[Id>cpl_segment_list_uuid]" 
cpl.xpath(expression).each do |f| 

은 그것은 "각이 할"실행 하지만 이전과 같은

cpl.css("Segment:contains(\"#{cpl_segment_list_uuid}\") > Resource").each do |f| 

같은 내부 노드를하지 않았다

,

그리고 "만약"-condition, 같은 문제 :

if cpl.at("Segment/Id:contains(\"#{cpl_segment_list_uuid}\")").each do|f| 
#some code 
end 

UPDATE 2016/18/10은

사실 나는 아직도 자원 (4)의 오른쪽 번호를하지만, 각 세그먼트별로 분리되지 않는다. 따라서 각 세그먼트에는 동일한 네 가지 리소스가 있습니다.

왜 내가 모든 리소스의 이중 번호를 얻지 못하는지, "Segment"-loop에 배열을 만듭니다.

#first each do 
cpls.each_with_index do |(cpl_uuid, mycpl), index| 
cpl_filename = mycpl 
cpl_file = File.open("#{resource_uri}/#{cpl_filename}") 
cpl = Nokogiri::XML(cpl_file).remove_namespaces! 

#get UUID for UUID checks 
cpl_uuid = cpl.css("Id").first.text.gsub(/\n/,"") 
cpl_root_edit_rate = cpl.css("EditRate").first.text.gsub(/\s+/, "\/") 

    #second each do 
    cpl.css("Segment").each do |s| # loop segment 
     cpl_segment_list_uuid = s.css("Id").first.text.gsub(/\n/,"") #uuid of segment list 
     array_for_resource_data = Array.new 

     #third each do 
     s.css("Resource").each do |f| #loop resources #all resources 
     s.search('//A | //B').each do |f| #selecting only resources "A" and "B" 
      cpl_A = f.css("A").text.gsub(/\n/,"") # uuid of A 
      cpl_B = f.css("B").text.gsub(/\n/,"") # uuid of B 
     end #third 
    end #second 
end #first 

내 업데이트가 당신에게 더 많은 정보를 줄 것이다 희망 :

이 본 코드입니다. 도움과 답변을 해주셔서 대단히 감사합니다!

업데이트

세그먼트의 두 출력의 문제가 해결된다 2016/31/10. 이제 세그먼트 아래에 각 시퀀스마다 루프가 하나 더 있습니다.

cpl.css("Segment").each do |u| 
    segment_list_uuid = u.css("Id").first.text.gsub(/\n/,"") 
    sequence_list_uuid_arr = Array.new 

    u.xpath("//SequenceList[//*[starts-with(name(),'Sequence')]]").each do |s| 
     sequence_list_uuid = s.css("TrackId").first.text#.gsub(/\n/,"") 
     sequence_list_uuid_arr.push(cpl_sequence_list_uuid) 

    #following some resource nodes 
    s.css("Resource").each do |f| 
     asset_uuid = f.css("TrackFileId").text.gsub(/\n/,"") 
     resource_uuid = f.css("Id").text.gsub(/\n/,"") 
     edit_rate = f.css("EditRate").text.gsub(/\s+/, "\/") 
     #some more code 
    end #resource 
    end #sequence list 
end #segment 

이제 각 고유 시퀀스에서 다른 모든 "리소스"를 얻고 싶습니다. 나는 모든 다른 자원을 나열하고 수집 된 가치의 일부를 요약해야합니다.

동일한 "시퀀스 ID"에서 다른 값 (하위 노드)을 가진 각 리소스를 수집하는 방법이 있습니까? 현재로서는 어떤 해결책이 있는지 모르겠다. 그래서 내가 보여 줄 수있는 코드가 없으므로 부분적으로 작동 할 것이다.

"리소스"루프에 대한 each_with_index가 작동하지 않습니다.

내 새로운 문제를 해결할 수있는 아이디어 나 방법이 있습니까?

답변

0

오히려 전체 문서를 검색하는 것보다 현재 요소에서 XPath 쿼리를 고정합니다

resource.search('.//A | .//B') 

.//

을보십시오.

elem = doc.search('ImageSequence').first 
elem.search('//A') # returns all A in the whole document 
elem.search('.//A') # returns all A inside element