Class: XML::Mapping::SingleAttributeNode

Inherits:
Node
  • Object
show all
Defined in:
lib/xml/mapping/base.rb

Overview

Base class for node types that map some XML data to a single attribute of their mapping class.

All node types that come with xml-mapping except one (ChoiceNode) inherit from SingleAttributeNode.

Direct Known Subclasses

BooleanNode, NumericNode, SubObjectBaseNode, TextNode

Defined Under Namespace

Classes: NoAttrValueSet

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ SingleAttributeNode

Initializer. owner is the owning mapping class (gets passed to the superclass initializer and therefore put into @owner). The second parameter (and hence the first parameter to the node factory method), attrname, is a symbol that names the mapping class attribute this node should map to. It gets stored into @attrname, and the attribute (an r/w attribute of name attrname) is added to the mapping class (using attr_accessor).

In the initializer, two option arguments -- :optional and :default_value -- are processed in SingleAttributeNode:

Supplying :default_value=>obj makes obj the default value for this attribute. When unmarshalling (loading) an object from an XML source, the attribute will be set to this value if nothing was provided in the XML; when marshalling (saving), the attribute won't be saved if it is set to the default value.

Providing just :optional=>true is equivalent to providing :default_value=>nil.



662
663
664
665
666
667
668
669
670
# File 'lib/xml/mapping/base.rb', line 662

def initialize(*args)
  @attrname,*args = super(*args)
  @owner.add_accessor @attrname
  if @options[:optional] and not(@options.has_key?(:default_value))
    @options[:default_value] = nil
  end
  initialize_impl(*args)
  args
end

Instance Method Details

#default_when_xpath_errObject

utility method to be used by implementations of #extract_attr_value. Calls the supplied block, catching XML::XXPathError and mapping it to NoAttrValueSet. This is for the common case that an implementation considers an attribute value not to be present in the XML if some specific sub-path does not exist.



752
753
754
755
756
757
758
# File 'lib/xml/mapping/base.rb', line 752

def default_when_xpath_err # :yields:
  begin
    yield
  rescue XML::XXPathError => err
    raise NoAttrValueSet, "Attribute #{@attrname} not set (XXPathError: #{err})"
  end
end

#extract_attr_value(xml) ⇒ Object

(to be overridden by subclasses) Extract and return the value of the attribute this node is responsible for (@attrname) from xml. If the implementation decides that the attribute value is "unset" in xml, it should raise NoAttrValueSet in order to initiate proper handling of possibly supplied :optional and :default_value options (you may use #default_when_xpath_err for this purpose).



713
714
715
# File 'lib/xml/mapping/base.rb', line 713

def extract_attr_value(xml)
  raise "abstract method called"
end

#initialize_impl(*args) ⇒ Object

this method was retained for compatibility with xml-mapping 0.8.

It used to be the initializer to be implemented by subclasses. The arguments (args) are those still unprocessed by SingleAttributeNode's initializer.

In xml-mapping 0.9 and up, you should just override initialize() and call super.initialize. The returned array is the same args array.



679
680
# File 'lib/xml/mapping/base.rb', line 679

def initialize_impl(*args)
end

#is_present_in?(obj) ⇒ Boolean

(overridden) returns true if and only if the value of this node's attribute in obj is non-nil.

Returns:

  • (Boolean)


761
762
763
# File 'lib/xml/mapping/base.rb', line 761

def is_present_in? obj
  nil != obj.send(:"#{@attrname}")
end

#obj_initializing(obj, mapping) ⇒ Object

:nodoc:



737
738
739
740
741
742
743
744
745
# File 'lib/xml/mapping/base.rb', line 737

def obj_initializing(obj,mapping)  # :nodoc:
  if @options.has_key?(:default_value) and (mapping==nil || mapping==@mapping)
    begin
      obj.send :"#{@attrname}=", @options[:default_value].clone
    rescue
      obj.send :"#{@attrname}=", @options[:default_value]
    end
  end
end

#obj_to_xml(obj, xml) ⇒ Object

:nodoc:



716
717
718
719
720
721
722
723
724
725
726
727
728
729
# File 'lib/xml/mapping/base.rb', line 716

def obj_to_xml(obj,xml) # :nodoc:
  value = obj.send(:"#{@attrname}")
  if @options.has_key? :default_value
    unless value == @options[:default_value]
      set_attr_value(xml, value)
    end
  else
    if value == nil
      raise XML::MappingError, "no value, and no default value, for attribute: #{@attrname}"
    end
    set_attr_value(xml, value)
  end
  true
end

#set_attr_value(xml, value) ⇒ Object

(to be overridden by subclasses) Write value, which is the current value of the attribute this node is responsible for (@attrname), into (the correct sub-nodes, attributes, whatever) of xml.



734
735
736
# File 'lib/xml/mapping/base.rb', line 734

def set_attr_value(xml, value)
  raise "abstract method called"
end

#xml_to_obj(obj, xml) ⇒ Object

:nodoc:



690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
# File 'lib/xml/mapping/base.rb', line 690

def xml_to_obj(obj,xml)  # :nodoc:
  begin
    obj.send :"#{@attrname}=", extract_attr_value(xml)
  rescue NoAttrValueSet => err
    unless @options.has_key? :default_value
      raise XML::MappingError, "no value, and no default value: #{err}"
    end
    begin
      obj.send :"#{@attrname}=", @options[:default_value].clone
    rescue
      obj.send :"#{@attrname}=", @options[:default_value]
    end
  end
  true
end