I am using nokogiri and ruby to script some deployment scripts and I need to update the file from many sources of information. The first file I loop through I just do a simple replace with gsub
File.open(@sql_file, 'w') { |file| file.puts text.gsub(/#{find}/, replace.to_s) }
That works great for the first file but for the second time I need to parse out that text I replaced initially and potentially update it. Using Nokogiri I have come up with the following:
def write_changes(find, replace)
text = ''
text = File.read(@sql_file)
if text =~ /#{find}/
File.open(@sql_file, 'w') do |file|
file.puts text.gsub(/#{find}/, replace.to_s)
end
else
xml = Nokogiri::XML.parse(replace)
element xml.at_xpath('//items')
end
end
Maybe not very ruby:ish but it works. The problem here though is that I need to parse out
<items id="">
<item />
</items>
from the text in the file so that I can use Nokogiri to update that text and later replace it with my changes.
So basically I guess I need to find the startindex of my items tag where the id matches and then cut out everything from <items id=""> to </items>.
Does it make sense? Should I clarify further?
EDIT 1. I have something somewhat working but I can’t figure out the last part.
original = text[begin_index, end_index]
xml2 = Nokogiri::XML.parse(original)
update_element_values(xml, xml2)
add_missing_elements(xml, xml2)
# text[begin_index, end_index] = xml2.root.to_s
text.insert(begin_index, xml2.root.to_s)
File.open(@sql_file, 'w') { |file| file.puts text }
if I uncomment the line that does a replace between indexes I get some corrupt chopped up result with most of it missing.
If I use the insert version I get duplicates for every file I try to merge. What is the correct way to do replace between two indexes in a string in ruby?
My solution inspired by @Andrew’s comment was to use open the text as a html document to be able to navigate to the xpath and do replacement on that. After that is done i just clean up the generated html headers. Wish there was a better way though.