Reputation: 7102
I am trying to learn Nokogiri with some scenarios and am parsing the html code right now using it.
doc = Nokogiri::HTML($driver.page_source)
In my code I have muliple div sections which has some nested span and div tags as per below:
<div class="class1 class2 class3 class4" style="padding: 4px;" id="_28f331c5-3e42-4944-aa3f-15b68f453a2b">
<span class="class5" style="font-weight: bold; text-decoration: underline;">This is a String Text</span>
<div class="class6" dd:contenttype="content_type1" dd:concept="concept1" id="_8c83d6b3-55a1-4e88-b8af-9578bbfdef83">
<div class="class7">
<div class="class8" dd:contenttype="content_type2" dd:entityid="0" dd:entityversion="0" id="_cb48e502-9d87-451c-a7cf-4df104f21e51">
<div class="class9 class10" dd:btnfloatingstyle="top-right" dd:entitytexttype="resultval" id="_9e48a58b-3f06-4ce1-8a1e-fb7f4c5d1fc0" contenteditable="true"></div>
</div>
</div>
</div>
</div>
<div class="class1 class2 class3 class4" style="padding: 4px;" id="_28f331c5-3e42-4944-aa3f-15b68f453a2b">
<span class="class5" style="font-weight: bold; text-decoration: underline;">New String Text</span>
<div class="class6" dd:contenttype="content_type1" dd:concept="concept1" id="_8c83d6b3-55a1-4e88-b8af-9578bbfdef83">
<div class="class7">
<div class="class8" dd:contenttype="content_type2" dd:entityid="0" dd:entityversion="0" id="_cb48e502-9d87-451c-a7cf-4df104f21e51">
<div class="class9 class10" dd:btnfloatingstyle="top-right" dd:entitytexttype="resultval" id="_9e48a58b-3f06-4ce1-8a1e-fb7f4c5d1fc0" contenteditable="true"></div>
</div>
</div>
</div>
</div>
What I am looking for is when I pass a string "This is a String Text" as an input to a method, it should look into multiple div sections and return me the appropriate entire div section along with its nested span and div's.
Is there a direct way to achieve what I want using Nokogiri or any other API or will I need to write a method to traverse through the element, its parent and then the child??
Please suggest the direct way if there is any else I will write my own code to traverse.
Upvotes: 0
Views: 256
Reputation: 46836
If you need to get a node based on its child nodes, you will have to use an xpath-selector instead of a css-selector.
To get the div containing the span, do:
node = doc.at_xpath('//div[./span[text()="New String Text"]]')
Runnable example:
require 'nokogiri'
html = %q[
<body>
<div class="class1 class2 class3 class4" style="padding: 4px;" id="_28f331c5-3e42-4944-aa3f-15b68f453a2b">
<span class="class5" style="font-weight: bold; text-decoration: underline;">This is a String Text</span>
<div class="class6" dd:contenttype="content_type1" dd:concept="concept1" id="_8c83d6b3-55a1-4e88-b8af-9578bbfdef83">
<div class="class7">
<div class="class8" dd:contenttype="content_type2" dd:entityid="0" dd:entityversion="0" id="_cb48e502-9d87-451c-a7cf-4df104f21e51">
<div class="class9 class10" dd:btnfloatingstyle="top-right" dd:entitytexttype="resultval" id="_9e48a58b-3f06-4ce1-8a1e-fb7f4c5d1fc0" contenteditable="true"></div>
</div>
</div>
</div>
</div>
<div class="class1 class2 class3 class4" style="padding: 4px;" id="_28f331c5-3e42-4944-aa3f-15b68f453a2b">
<span class="class5" style="font-weight: bold; text-decoration: underline;">New String Text</span>
<div class="class6" dd:contenttype="content_type1" dd:concept="concept1" id="_8c83d6b3-55a1-4e88-b8af-9578bbfdef83">
<div class="class7">
<div class="class8" dd:contenttype="content_type2" dd:entityid="0" dd:entityversion="0" id="_cb48e502-9d87-451c-a7cf-4df104f21e51">
<div class="class9 class10" dd:btnfloatingstyle="top-right" dd:entitytexttype="resultval" id="_9e48a58b-3f06-4ce1-8a1e-fb7f4c5d1fc0" contenteditable="true">asdf</div>
</div>
</div>
</div>
</div>
</body>
]
doc = Nokogiri::HTML.parse(html)
puts doc.at_xpath('//div[./span[text()="New String Text"]]').to_html
#=> <div class="class1 class2 class3 class4" style="padding: 4px;" id="_28f331c5-3e42-4944-aa3f-15b68f453a2b">
#=> <span class="class5" style="font-weight: bold; text-decoration: underline;">New String Text</span>
#=> <div class="class6" dd:contenttype="content_type1" dd:concept="concept1" id="_8c83d6b3-55a1-4e88-b8af-9578bbfdef83">
#=> <div class="class7">
#=> <div class="class8" dd:contenttype="content_type2" dd:entityid="0" dd:entityversion="0" id="_cb48e502-9d87-451c-a7cf-4df104f21e51">
#=> <div class="class9 class10" dd:btnfloatingstyle="top-right" dd:entitytexttype="resultval" id="_9e48a58b-3f06-4ce1-8a1e-fb7f4c5d1fc0" contenteditable="true">asdf</div>
#=> </div>
#=> </div>
#=> </div>
#=> </div>
Upvotes: 1