# XML/HTML batch generator

As part of an exercise I've written some code to generate multiple HTML files based on information stored in a couple of XML files. I'm not really sure how much code you'd need to evaluate my function so this is most of the relevant code regarding the actual HTML from XML generation:

  # search taxonomy.xml for nodes with the attribute 'atlas_node_id'
# to get a NodeSet of all the destinations
destinations = tax_file.css('[atlas_node_id]')

# cd to directory you want to create the files in
FileUtils.cd(directory)

destinations.each do |destination|
# temp variable to make code easier to read later on
id = destination.attribute('atlas_node_id').value

html = Nokogiri::HTML::Builder.new do |doc|
doc.html{
doc.title destination.children[1].content
}

doc.body{
doc.h1{
doc.text destination.children[1].content
}

# check if there is a destination higher in the taxonomy and display
# the relevant link if so.
if !(destination.parent.attribute('atlas_node_id').nil?)
file = destination.parent.children[1].content + ".html"
doc.a(:href => file){
doc.text destination.parent.children[1].content
}
end

# I chose to show the overview content since this exists for every
# destination
doc.p{
node = dest_file.xpath("//destination[@atlas_id = #{id}]").first
doc.text node.xpath(".//introductory/introduction/overview").text unless
node.nil?
}
}
}
end

# write file using destination name as filename
filename = destination.children[1].content + ".html"
directory << File.open(filename,'w').write(html.to_html)
end


At the moment the XML files in questions are small (there are only 24 destinations in total) so everything works without problems. How can I refactor this to make if more performant for situations where there are many thousands of destinations?

If your problem is speed and the generated HTML is as easy as it look in your example code, then I would not use the Nokogiri Builder.

Take a HTML-Template and build your files according this template.

Example (without an example XML I was not able to check it):

# search taxonomy.xml for nodes with the attribute 'atlas_node_id'
# to get a NodeSet of all the destinations
destinations = tax_file.css('[atlas_node_id]')

destinations.each do |destination|
# temp variable to make code easier to read later on
id = destination.attribute('atlas_node_id').value

# write file using destination name as filename
filename = destination.children[1].content + ".html"
File.open(File.join(directory,filename),'w'){|html|
html << <<HTML % destination.children[1].content
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<title>%s</title>
<body>
HTML
html << "<h1>%s</h1>\n" % destination.children[1].content

# check if there is a destination higher in the taxonomy and display
# the relevant link if so.
if !(destination.parent.attribute('atlas_node_id').nil?)
file = destination.parent.children[1].content + ".html"
html << '<a href = "%s">%s</a>' % [file,destination.parent.children[1].content]
html << "\n"
end

# I chose to show the overview content since this exists for every
# destination
node = dest_file.xpath("//destination[@atlas_id = #{id}]").first
html << "<p>%s</p>\n" % node.xpath(".//introductory/introduction/overview").text unless node.nil?
html << "</body>"
}

end