Skip to content

Instantly share code, notes, and snippets.

@armw4
Last active December 31, 2015 19:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save armw4/8033254 to your computer and use it in GitHub Desktop.
Save armw4/8033254 to your computer and use it in GitHub Desktop.
An experiment with nokogiri. Provides a DSL for ad-hoc element generation similar to how Nokogiri::XML::Builder works. In a separate experiment, I plan to allow composition with builders. You'll be able to heterogeneously mix the builder API with my API.

by Antwan Wimberly

require 'nokogiri'

module Kernel
  def element(name, *args, &block)
    fragment = Nokogiri::XML.fragment nil

    element = fragment.document.create_element name, *args

    element.add_child yield if block_given?

    element
  end
end

def add_node(selector, node, &block)
  modified_doc = open "Web.config" do |f|
    doc = Nokogiri::XML(f)

    target_node = doc.at_css selector

    if not target_node # no bueno
      if block_given? # they told us how to handle a non existent node
        yield doc
      else # well we can't just go on pretending like everything worked out ok
        raise "Could locate an element with the css selector '#{selector}'."
      end
    else # everything is peachy, we found the node and can blindly append it to the target
      target_node.add_child node
    end

    doc
  end

  open "Web.config", 'w+' do |f|
    modified_doc.write_xml_to f
  end
end

node = element "div", "contents", :class => "container"

add_node 'configuration appSettings', node

add_node 'configuration appSetting', node do |doc|
  doc.at_css('configuration').add_child element("appSetting") { node }
end

x = element("zero") {
  element("99") {
    node
  }
}

puts x.to_xml # => <zero>
              #      <99>
              #        <div class="container">contents</div>
              #      </99>
              #    </zero>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings />
</configuration>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment