Skip to content

Instantly share code, notes, and snippets.

@doertedev
Created June 20, 2017 19:37

Revisions

  1. @doertedev-instana doertedev-instana created this gist Jun 20, 2017.
    69 changes: 69 additions & 0 deletions xml_css.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,69 @@
    require 'nokogiri'
    require 'utils/simpleconfig'

    class XML_CSS < Inspec.resource(1)
    name 'xml_css'

    desc 'XML for Chef Inspec using Nokogiri\'s CSS selector feature'

    example '
    Given this set of XML:
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <this>
    <but>
    <some>XML</some>
    </but>
    <but>
    <some>More</some>
    </but>
    </this>
    Run this
    describe xml_css "/tmp/file.xml", "but+but" do
    its("inner_text") { should eq "More" }
    end
    The CSS is being put as a second variable in the describe block so we
    can blindly call the its-descriptor as a Nokogiri::XML::NodeSet-method.
    This way, not only to_s, to_a but also empty? and length are working as
    expected.
    '

    def initialize(filename, xpath)
    @file = inspec.file(filename)
    @file_content = @file.content

    # check if file is available
    if !@file.file?
    skip_resource "Can't find file \"#{@path}\""
    return @params = {}
    end

    # check if file is readable
    if @file_content.nil? && !@file.empty?
    skip_resource "Can't read file \"#{@path}\""
    return @params = {}
    end
    begin
    doc = Nokogiri::XML(@file_content) do |config|
    config.options = Nokogiri::XML::ParseOptions::NOERROR
    end
    doc.remove_namespaces!
    rescue
    unless doc.is_a?(Nokogiri::XML::Document)
    skip_resource "Error parsing #{@file}'s XML!"
    end
    end
    @object = doc.root.css(xpath)
    @type = @object.class
    skip_resource "#{@file}'s XML doesn't yielded nil at css-path #{xpath}" if @type.nil?
    end

    def method_missing(*keys)
    skip_resource 'Please specify a method to call!' unless keys[0].is_a? String
    skip_resource 'Unknown method called!' unless @object.methods.include? keys[0]
    return @object.send keys[0].to_sym
    end
    end