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