module Nokogiri::ClassResolver

def related_class(class_name)


# => Nokogiri::HTML4::Document
ThisIsATopLevelClass.new.related_class("Document")
class ThisIsATopLevelClass < Nokogiri::HTML4::Builder ; end

And even if it's a subclass, this will iterate through the superclasses:

# => Loofah::HTML::DocumentFragment
Loofah::HTML::Document.new.related_class("DocumentFragment")

Note this will also work for subclasses that follow the same convention, e.g.:

# => Nokogiri::HTML4::DocumentFragment
Nokogiri::HTML4::Document.new.related_class("DocumentFragment")
# => Nokogiri::XML::DocumentFragment
Nokogiri::XML::Document.new.related_class("DocumentFragment")

Some examples:

Find a class constant within the

related_class(class_name) → Class
:call-seq:
def related_class(class_name)
  klass = nil
  inspecting = self.class
  while inspecting
    namespace_path = inspecting.name.split("::")[0..-2]
    inspecting = inspecting.superclass
    next unless VALID_NAMESPACES.include?(namespace_path.last)
    related_class_name = (namespace_path << class_name).join("::")
    klass = begin
      Object.const_get(related_class_name)
    rescue NameError
      nil
    end
    break if klass
  end
  klass
end