class Oga::XML::Element

Class that contains information about an XML element such as the name, attributes and child nodes.

Constants

XMLNS_PREFIX

The attribute prefix/namespace used for registering element namespaces.

@return [String]

Attributes

attributes[RW]

@return [Array<Oga::XML::Attribute>]

name[RW]

@return [String]

namespace_name[R]

@return [String]

namespaces[W]

@return [Hash]

Public Class Methods

new(options = {}) click to toggle source

@param [Hash] options

@option options [String] :name The name of the element.

@option options [String] :namespace_name The name of the namespace.

@option options [Array<Oga::XML::Attribute>] :attributes The attributes

of the element as an Array.
Calls superclass method
# File lib/oga/xml/element.rb, line 34
def initialize(options = {})
  super

  @name                 = options[:name]
  @namespace_name       = options[:namespace_name]
  @attributes           = options[:attributes] || []
  @namespaces           = options[:namespaces] || {}
  @available_namespaces = nil

  link_attributes
  register_namespaces_from_attributes
end

Public Instance Methods

[](name)
Alias for: get
[]=(name, value)
Alias for: set
add_attribute(attribute) click to toggle source

Adds a new attribute to the element.

@param [Oga::XML::Attribute] attribute

# File lib/oga/xml/element.rb, line 100
def add_attribute(attribute)
  attribute.element = self

  attributes << attribute
end
attr(name)
Alias for: attribute
attribute(name) click to toggle source

Returns an attribute matching the given name (with or without the namespace).

@example

# find an attribute that only has the name "foo"
attribute('foo')

# find an attribute with namespace "foo" and name bar"
attribute('foo:bar')

@param [String|Symbol] name The name (with or without the namespace)

of the attribute.

@return [Oga::XML::Attribute]

# File lib/oga/xml/element.rb, line 67
def attribute(name)
  name_str, ns = if html?
    [name.to_s, nil]
  else
    split_name(name)
  end

  attributes.each do |attr|
    return attr if attribute_matches?(attr, ns, name_str)
  end

  return
end
Also aliased as: attr
available_namespaces() click to toggle source

Returns a Hash containing all the namespaces available to the current element.

@return [Hash]

# File lib/oga/xml/element.rb, line 253
def available_namespaces
  # HTML(5) completely ignores namespaces
  unless @available_namespaces
    if html?
      @available_namespaces = {}
    else
      merged = namespaces.dup
      node   = parent

      while node && node.respond_to?(:namespaces)
        node.namespaces.each do |prefix, ns|
          merged[prefix] = ns unless merged[prefix]
        end

        node = node.parent
      end

      @available_namespaces = merged
    end
  end

  @available_namespaces
end
default_namespace?() click to toggle source

Returns true if the current element resides in the default XML namespace.

@return [TrueClass|FalseClass]

# File lib/oga/xml/element.rb, line 169
def default_namespace?
  namespace == DEFAULT_NAMESPACE || namespace.nil?
end
flush_namespaces_cache() click to toggle source

Flushes the namespaces cache of the current element and all its child elements.

# File lib/oga/xml/element.rb, line 294
def flush_namespaces_cache
  @available_namespaces = nil
  @namespace            = nil

  children.each do |child|
    child.flush_namespaces_cache if child.is_a?(Element)
  end
end
get(name) click to toggle source

Returns the value of the given attribute.

@example

element.get('class') # => "container"

@see [#attribute]

# File lib/oga/xml/element.rb, line 89
def get(name)
  found = attribute(name)

  found ? found.value : nil
end
Also aliased as: []
inner_text() click to toggle source

Returns the text of the current element only.

@return [String]

# File lib/oga/xml/element.rb, line 183
def inner_text
  text = ''

  text_nodes.each do |node|
    text << node.text
  end

  text
end
inner_text=(text) click to toggle source

Sets the inner text of the current element to the given String.

@param [String] text

# File lib/oga/xml/element.rb, line 210
def inner_text=(text)
  text_node = XML::Text.new(:text => text)
  @children = NodeSet.new([text_node], self)
end
inspect() click to toggle source

@return [String]

# File lib/oga/xml/element.rb, line 216
def inspect
  segments = []

  [:name, :namespace, :attributes, :children].each do |attr|
    value = send(attr)

    if !value or (value.respond_to?(:empty?) and value.empty?)
      next
    end

    segments << "#{attr}: #{value.inspect}"
  end

  "Element(#{segments.join(' ')})"
end
literal_html_name?() click to toggle source

Returns true if the current element name is the name of one of the literal HTML elements.

@return [TrueClass|FalseClass]

# File lib/oga/xml/element.rb, line 307
def literal_html_name?
  Lexer::LITERAL_HTML_ELEMENTS.allow?(name)
end
namespace() click to toggle source

Returns the namespace of the element.

@return [Oga::XML::Namespace]

# File lib/oga/xml/element.rb, line 148
def namespace
  unless @namespace
    available  = available_namespaces
    @namespace = available[namespace_name] || available[XMLNS_PREFIX]
  end

  @namespace
end
namespace_name=(name) click to toggle source

@param [String] name

# File lib/oga/xml/element.rb, line 48
def namespace_name=(name)
  @namespace_name = name
  @namespace      = nil
end
namespaces() click to toggle source

Returns the namespaces registered on this element, or an empty Hash in case of an HTML element.

@return [Hash]

# File lib/oga/xml/element.rb, line 161
def namespaces
  html? ? {} : @namespaces
end
register_namespace(name, uri, flush = true) click to toggle source

Registers a new namespace for the current element and its child elements.

@param [String] name @param [String] uri @param [TrueClass|FalseClass] flush @see [Oga::XML::Namespace#initialize]

# File lib/oga/xml/element.rb, line 239
def register_namespace(name, uri, flush = true)
  if namespaces[name]
    raise ArgumentError, "The namespace #{name.inspect} already exists"
  end

  namespaces[name] = Namespace.new(:name => name, :uri => uri)

  flush_namespaces_cache if flush
end
self_closing?() click to toggle source

Returns `true` if the element is a self-closing element.

@return [TrueClass|FalseClass]

# File lib/oga/xml/element.rb, line 280
def self_closing?
  self_closing = children.empty?
  root         = root_node

  if root.is_a?(Document) and root.html? \
  and !HTML_VOID_ELEMENTS.allow?(name)
    self_closing = false
  end

  self_closing
end
set(name, value) click to toggle source

Sets the value of an attribute to the given value. If the attribute does not exist it is created automatically.

@param [String] name The name of the attribute, optionally including the

namespace.

@param [String] value The new value of the attribute.

# File lib/oga/xml/element.rb, line 113
def set(name, value)
  found = attribute(name)

  if found
    found.value = value
  else
    name_str, ns = split_name(name)

    attr = Attribute.new(
      :name           => name_str,
      :namespace_name => ns,
      :value          => value
    )

    add_attribute(attr)
  end
end
Also aliased as: []=
text() click to toggle source

Returns the text of all child nodes joined together.

@return [String]

# File lib/oga/xml/element.rb, line 176
def text
  children.text
end
text_nodes() click to toggle source

Returns any {Oga::XML::Text} nodes that are a direct child of this element.

@return [Oga::XML::NodeSet]

# File lib/oga/xml/element.rb, line 197
def text_nodes
  nodes = NodeSet.new

  children.each do |child|
    nodes << child if child.is_a?(Text)
  end

  nodes
end
unset(name) click to toggle source

Removes an attribute from the element.

@param [String] name The name (optionally including namespace prefix)

of the attribute to remove.

@return [Oga::XML::Attribute]

# File lib/oga/xml/element.rb, line 139
def unset(name)
  found = attribute(name)

  return attributes.delete(found) if found
end

Private Instance Methods

attribute_matches?(attr, ns, name) click to toggle source

@param [Oga::XML::Attribute] attr @param [String] ns @param [String] name @return [TrueClass|FalseClass]

# File lib/oga/xml/element.rb, line 351
def attribute_matches?(attr, ns, name)
  name_matches = attr.name == name
  ns_matches   = false

  if ns
    ns_matches = attr.namespace.to_s == ns

  elsif name_matches and !attr.namespace
    ns_matches = true
  end

  name_matches && ns_matches
end
register_namespaces_from_attributes() click to toggle source

Registers namespaces based on any “xmlns” attributes.

# File lib/oga/xml/element.rb, line 314
def register_namespaces_from_attributes
  flush = false

  attributes.each do |attr|
    # We're using `namespace_name` opposed to `namespace.name` as "xmlns"
    # is not a registered namespace.
    if attr.name == XMLNS_PREFIX or attr.namespace_name == XMLNS_PREFIX
      flush = true

      # Ensures we only flush the cache once instead of flushing it on
      # every register_namespace call.
      register_namespace(attr.name, attr.value, false)
    end
  end

  flush_namespaces_cache if flush
end
split_name(name) click to toggle source

@param [String] name @return [Array]

# File lib/oga/xml/element.rb, line 341
def split_name(name)
  segments = name.to_s.split(':')

  [segments.pop, segments.pop]
end