1
\$\begingroup\$

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.head{
          doc.title destination.children[1].content
          doc.link(rel: 'stylesheet', href: "all.css")
        }

        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?

\$\endgroup\$
1
\$\begingroup\$

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>      
<head>
<title>%s</title>
<link rel='stylesheet' href="all.css">
</head>
<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
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.