Class: SDL4R::Tag

Inherits:
Object
  • Object
show all
Defined in:
lib/sdl4r/tag.rb

Overview

SDL documents are made of Tags.

See the README for a longer explanation on SDL documents.

Do not assume that methods returning sets (Hash, Array, etc) of children/values/attributes/etc in this class returns copies or implementations. It can be one or the other depending on the method. The implementations are designed to be correct and somewhat efficient, not too protect the Tag internal state from ill-use of the returned values.

Authors

Daniel Leuck, Philippe Vosges

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(namespace, name = nil, &block) ⇒ Tag

Creates an empty tag in the given namespace. If the namespace is nil it will be coerced to an empty String.

tag = Tag.new("name")
tag = Tag.new("namespace", "name")

tag = Tag.new("fruit") do
  add_value 2
  new_child("orange") do
    set_attribute("quantity", 2)
  end
end

which builds the following SDL structure

fruit 2 {
  orange quantity=2
}

If you provide a block that takes an argument, you will write the same example, as follows:

tag = Tag.new("fruit") do |t|
  t.add_value 2
  t.new_child("orange") do
    set_attribute("quantity", 2)
  end
end

In this case, the current context is not the new Tag anymore but the context of your code.

Raises

ArgumentError if the name is not a legal SDL identifier (see SDL4R#validate_identifier) or the namespace is non-blank and is not a legal SDL identifier.

Raises:

  • (ArgumentError)


142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/sdl4r/tag.rb', line 142

def initialize(namespace, name = nil, &block)
  namespace, name = to_ns_n namespace, name


  raise ArgumentError, "tag namespace must be a String" unless namespace.is_a? String
  raise ArgumentError, "tag name must be a String" unless name.is_a? String

  SDL4R.validate_identifier(namespace) unless namespace.empty?
  @namespace = namespace
  
  name = name.to_s.strip
  raise ArgumentError, "Tag name cannot be nil or empty" if name.empty?
  SDL4R.validate_identifier(name)
  @name = name
  
  @children = []
  @values = []
  
  # a Hash of Hash : {namespace => {name => value}}
  # The default namespace is represented by an empty string.
  @attributesByNamespace = {}

  if block_given?
    if block.arity > 0
      block[self]
    else
      instance_eval(&block)
    end
  end
end

Instance Attribute Details

#nameObject

the name of this Tag



47
48
49
# File 'lib/sdl4r/tag.rb', line 47

def name
  @name
end

#namespaceObject

the namespace of this Tag or an empty string when there is no namespace (i.e. default namespace).



52
53
54
# File 'lib/sdl4r/tag.rb', line 52

def namespace
  @namespace
end

Instance Method Details

#<<(o) ⇒ Object

Adds the given object as a child if it is a Tag, as an attribute if it is a Hash => value (supports namespaces), or as a value otherwise. If it is an Enumerable (e.g. Array), each of its elements is added to this Tag via this operator. If any of its elements is itself an Enumerable, then an anonymous tag is created and the Enumerable is passed to it via this operator (see the examples below).

tag << Tag.new("child")
tag << 123                          # new integer value
tag << "islamabad"                  # new string value
tag << { "metric:length" => 1027 }  # new attribute (with namespace)
tag << [nil, 456, "abc"]            # several values added

tag = Tag.new("tag")
tag << [[1, 2, 3], [4, 5, 6]]       # tag {
                                    #   1 2 3
                                    #   4 5 6
                                    # }

Of course, despite the fact that String is an Enumerable, it is considered as the type of values.

Returns self.

Use other accessors (#add_child, #add_value, #attributes, etc) for a stricter and less “magical” behavior.



236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
# File 'lib/sdl4r/tag.rb', line 236

def <<(o)
  if o.is_a?(Tag)
    add_child(o)
  elsif o.is_a?(Hash)
    o.each_pair { |key, value|
      key = key.to_s if key.is_a? Symbol
      namespace, key = key.split(/:/) if key.match(/:/)
      namespace ||= ""
      set_attribute(namespace, key, value)
    }
  elsif o.is_a? String
    add_value(o)
  elsif o.is_a? Enumerable
    o.each { |item|
      if item.is_a? Enumerable and not item.is_a? String
        anonymous = new_child(ANONYMOUS_TAG_NAME)
        anonymous << item
      else
        self << item
      end
    }
  else
    add_value(o)
  end
  return self
end

#add_child(child) ⇒ Object

Add a child to this Tag.

child

The child to add

Returns the added child.

Raises:

  • (ArgumentError)


204
205
206
207
208
# File 'lib/sdl4r/tag.rb', line 204

def add_child(child)
  raise ArgumentError, "child is nil" unless child
  @children.push(child)
  return child
end

#add_value(v) ⇒ Object

Adds a value to this Tag. See SDL4R#coerce_or_fail to know about the allowable types.

v

The value to add

Raises an ArgumentError if the value is not a legal SDL type



485
486
487
488
# File 'lib/sdl4r/tag.rb', line 485

def add_value(v)
  @values.push(SDL4R::coerce_or_fail(v))
  return nil
end

#attribute(namespace, key = nil) ⇒ Object

attribute(key)

attribute(namespace, key)

Returns the attribute of the specified namespace of specified key or nil if not found.



596
597
598
599
600
# File 'lib/sdl4r/tag.rb', line 596

def attribute(namespace, key = nil)
  namespace, key = to_ns_n namespace, key
  attributes = @attributesByNamespace[namespace]
  return attributes.nil? ? nil : attributes[key]
end

#attributes(namespace = nil, &block) ⇒ Object

Returns a Hash of the attributes of the specified namespace (default is all) or enumerates them.

tag.attributes # => { "length" => 123, "width" = 25.4, "orig:color" => "gray" }
tag.attributes("orig") do |namespace, key, value|
  p "#{namespace}:#{key} = #{value}"
end
namespace

namespace of the returned attributes. If nil, all attributes are returned with qualified names (e.g. “meat:color”). If “”, attributes of the default namespace are returned.



638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
# File 'lib/sdl4r/tag.rb', line 638

def attributes(namespace = nil, &block) # :yields: namespace, key, value
  namespace = namespace.id2name if namespace.is_a? Symbol
  
  if block_given?
    each_attribute(namespace, &block)
    
  else
    if namespace.nil?
      hash = {}

      each_attribute do | attr_namespace, key, value |
        qualified_name = attr_namespace.empty? ? key : attr_namespace + ':' + key
        hash[qualified_name] = value
      end

      return hash

    else
      return @attributesByNamespace[namespace]
    end
  end
end

#attributes=(attribute_hash) ⇒ Object

Sets all the attributes of the default namespace for this Tag in one operation.

See #set_attributes.



744
745
746
# File 'lib/sdl4r/tag.rb', line 744

def attributes=(attribute_hash)
  set_attributes(attribute_hash)
end

#child(*args) ⇒ Object

child # => first child

child(name) # => first child of specified name (any namespace)
child(true, name) # => first child (or descendant) of specified name (any namspace)
child(namespace, name) # => first child of specified namespace and name
child(recursive, namespace, name)

Get the first child with the given name, optionally using a recursive search.

name

the name of the child Tag. If nil, the first child is returned (nil if there are

no children at all).

Returns the first child tag having the given name or nil if no such child exists



384
385
386
387
388
389
390
391
392
# File 'lib/sdl4r/tag.rb', line 384

def child(*args)
  recursive, namespace, name = to_rec_ns_n(*args)

  if namespace.nil? and name.nil?
    return @children.first
  else
    each_child(recursive, namespace, name) { |child| return child }
  end
end

#child_countObject

Returns the number of children Tag.



304
305
306
# File 'lib/sdl4r/tag.rb', line 304

def child_count
  @children.size
end

#children(*args, &block) ⇒ Object

children(recursive)

children(recursive, name)
children(recursive, namespace, name)

children(recursive) { |child| ... }
children(recursive, name) { |child| ... }
children(recursive, namespace, name) { |child| ... }

Returns an Array of the children Tags of this Tag or enumerates them.

recursive

if true children and all descendants will be returned. False by default.

name

if not nil, only children having this name will be returned. Nil by default.

namespace

use nil for all namespaces and “” for the default one. Nil by default.

tag.children # => array of the children
tag.children(true) { |descendant| ... }

tag.children(false, "name") # => children of name "name"
tag.children(false, "ns", nil) # => children of namespace "ns"


328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
# File 'lib/sdl4r/tag.rb', line 328

def children(*args, &block) # :yields: child
  recursive, namespace, name = to_rec_ns_n(*args)

  if block_given?
    each_child(recursive, namespace, name, &block)
    return nil
    
  else
    unless recursive or name or namespace
      return @children
      
    else
      result = []
      each_child(recursive, namespace, name) { |child|
        result << child
      }
      return result
    end
  end
end

#children_to_string(line_prefix = "", s = "") ⇒ Object

Returns a string representation of the children tags.

linePrefix

a prefix to insert before every line.

s

a String that receives the string representation

TODO: break up long lines using the backslash



924
925
926
927
928
929
930
# File 'lib/sdl4r/tag.rb', line 924

def children_to_string(line_prefix = "", s = "")
  @children.each do |child|
    s << child.to_string(line_prefix) << $/
  end
  
  return s
end

#children_values(name = nil) ⇒ Object

Returns the values of all the children with the given name. If the child has more than one value, all the values will be added as an array. If the child has no value, nil will be added. The search is not recursive.

name

if nil, all children are considered (nil by default).



354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
# File 'lib/sdl4r/tag.rb', line 354

def children_values(name = nil)
  name = name.id2name if name.is_a? Symbol
  
  children_values = []
  each_child(false, name) { |child|
    case child.values.size
    when 0
      children_values << nil
    when 1
      children_values << child.value
    else
      children_values << child.values
    end
  }
  return children_values
end

#clear_attributes(namespace = nil) ⇒ Object

Clears the attributes of the specified namespace or all the attributes if namespace is nil.



680
681
682
683
684
685
686
687
# File 'lib/sdl4r/tag.rb', line 680

def clear_attributes(namespace = nil)
  if namespace.nil?
    @attributesByNamespace.clear
  else
    namespace = namespace.id2name if namespace.is_a? Symbol
    @attributesByNamespace.delete(namespace)
  end
end

#clear_childrenObject

Removes all children.



275
276
277
278
# File 'lib/sdl4r/tag.rb', line 275

def clear_children
  @children = []
  nil
end

#clear_valuesObject

Removes all values.



513
514
515
516
# File 'lib/sdl4r/tag.rb', line 513

def clear_values
  @values = []
  nil
end

#eql?(o) ⇒ Boolean Also known as: ==

Returns true if this tag (including all of its values, attributes, and children) is equivalent to the given tag.

Returns true if the tags are equivalet

Returns:

  • (Boolean)


937
938
939
940
# File 'lib/sdl4r/tag.rb', line 937

def eql?(o)
  # this is safe because to_string() dumps the full state
  return o.is_a?(Tag) && o.to_string == to_string;
end

#has_attribute?(namespace = nil, key = nil) ⇒ Boolean

Indicates whether there is at least an attribute in this Tag.

has_attribute?

Indicates whether there is the specified attribute exists in this Tag.

has_attribute?(key)
has_attribute?(namespace, key)

Returns:

  • (Boolean)


609
610
611
612
613
614
615
616
617
618
619
620
# File 'lib/sdl4r/tag.rb', line 609

def has_attribute?(namespace = nil, key = nil)
  namespace, key = to_ns_n namespace, key

  if namespace or key
    attributes = @attributesByNamespace[namespace]
    return attributes.nil? ? false : attributes.has_key?(key)

  else
    attributes { return true }
    return false
  end
end

#has_attributes?Boolean

Returns:

  • (Boolean)


622
623
624
# File 'lib/sdl4r/tag.rb', line 622

def has_attributes?
  !@attributesByNamespace.empty?
end

#has_child?(namespace, name = :DEFAULT) ⇒ Boolean

Indicates whether the child Tag of given name exists.

name

name of the searched child Tag

has_child?(name)
has_child?(namespace, name)

Returns:

  • (Boolean)


401
402
403
404
405
406
407
408
# File 'lib/sdl4r/tag.rb', line 401

def has_child?(namespace, name = :DEFAULT)
  if name == :DEFAULT
    name = namespace
    namespace = nil
  end
  
  !child(namespace, name).nil?
end

#has_children?Boolean

Indicates whether there are children Tag.

Returns:

  • (Boolean)


412
413
414
# File 'lib/sdl4r/tag.rb', line 412

def has_children?
  !@children.empty?
end

#has_value?(v) ⇒ Boolean

Returns true if v is a value of this Tag’s.

Returns:

  • (Boolean)


492
493
494
# File 'lib/sdl4r/tag.rb', line 492

def has_value?(v)
  @values.include?(v)
end

#has_values?Boolean

Returns:

  • (Boolean)


547
548
549
# File 'lib/sdl4r/tag.rb', line 547

def has_values?
  !@values.empty?
end

#hashObject

Returns The hash (based on the output from toString())



945
946
947
# File 'lib/sdl4r/tag.rb', line 945

def hash
  return to_string.hash
end

#new_child(*args, &block) ⇒ Object

Creates a new child tag. Can take a block so that you can write something like:

car = Tag.new("car") do
  new_child("wheels") do
    self << 4
  end
end

The context of execution of the given block is the child instance. If you provide a block that takes a parameter (see below), the context is the context of your code:

car = Tag.new("car") do |child|
  child.new_child("wheels") do |grandchild|
    grandchild << 4
  end
end

Returns the created child Tag.



194
195
196
# File 'lib/sdl4r/tag.rb', line 194

def new_child(*args, &block)
  return add_child Tag.new(*args, &block)
end

#read(input) ⇒ Object

Adds all the tags specified in the given IO, String, Pathname or URI to this Tag.

Returns this Tag after adding all the children read from input.



774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
# File 'lib/sdl4r/tag.rb', line 774

def read(input)
  if input.is_a? String
    read_from_io(true) { StringIO.new(input) }

  elsif input.is_a? Pathname
    read_from_io(true) { input.open("r:UTF-8") }

  elsif input.is_a? URI
    read_from_io(true) { input.open }

  else
    read_from_io(false) { input }
  end
  
  return self
end

#read_from_io(close_io) ⇒ Object

Reads and parses the io returned by the specified block and closes this io if close_io is true.



793
794
795
796
797
798
799
800
801
802
803
804
805
806
# File 'lib/sdl4r/tag.rb', line 793

def read_from_io(close_io)
  io = yield

  begin
    SDL4R::Reader.from_io(io).each_tag(true) do |tag|
      add_child(tag)
    end

  ensure
    if close_io
      io.close rescue IOError
    end
  end
end

#remove_attribute(namespace, key = nil) ⇒ Object

remove_attribute(key)

remove_attribute(namespace, key)

Removes the attribute, whose name and namespace are specified.

key

name of the removed atribute

namespace

namespace of the removed attribute (equal to “”, default namespace, by default)

Returns the value of the removed attribute or nil if it didn’t exist.



671
672
673
674
675
# File 'lib/sdl4r/tag.rb', line 671

def remove_attribute(namespace, key = nil)
  namespace, key = to_ns_n namespace, key
  attributes = @attributesByNamespace[namespace]
  return attributes.nil? ? nil : attributes.delete(key)
end

#remove_child(child) ⇒ Object

Remove a child from this Tag

child

the child to remove

Returns true if the child exists and is removed



269
270
271
# File 'lib/sdl4r/tag.rb', line 269

def remove_child(child)
  return !@children.delete(child).nil?
end

#remove_value(v) ⇒ Object

Removes the first occurence of the specified value from this Tag.

v

The value to remove

Returns true If the value exists and is removed



502
503
504
505
506
507
508
509
# File 'lib/sdl4r/tag.rb', line 502

def remove_value(v)
  index = @values.index(v)
  if index
    return !@values.delete_at(index).nil?
  else
    return false
  end
end

#set_attribute(namespace, key, value = :default) ⇒ Object

set_attribute(key, value)

set_attribute(namespace, key, value)

Set an attribute in the given namespace for this tag. The allowable attribute value types are the same as those allowed for #add_value.

namespace

The namespace for this attribute

key

The attribute key

value

The attribute value

Raises ArgumentError if the key is not a legal SDL identifier (see SDL4R#validate_identifier), or the namespace is non-blank and is not a legal SDL identifier, or thevalue is not a legal SDL type

Raises:

  • (ArgumentError)


565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
# File 'lib/sdl4r/tag.rb', line 565

def set_attribute(namespace, key, value = :default)
  if value == :default
    value, key, namespace = key, namespace, ""
  end
  namespace = namespace.id2name if namespace.is_a? Symbol
  key = key.id2name if key.is_a? Symbol

  raise ArgumentError,
    "attribute namespace must be a String or a Symbol" unless namespace.is_a? String
  raise ArgumentError, "attribute key must be a String or a Symbol" unless key.is_a? String
  raise ArgumentError, "attribute key cannot be empty" if key.empty?

  SDL4R.validate_identifier(namespace) unless namespace.empty?
  SDL4R.validate_identifier(key)

  attributes = @attributesByNamespace[namespace]
  
  if attributes.nil?
    attributes = {}
    @attributesByNamespace[namespace] = attributes
  end
  
  attributes[key] = SDL4R.coerce_or_fail(value)
end

#set_attributes(namespace, attribute_hash = nil) ⇒ Object

set_attributes(attribute_hash)

set_attributes(namespace, attribute_hash)

Sets the attributes specified by a Hash in the given namespace in one operation. The previous attributes of the specified namespace are removed. See #set_attribute for allowable attribute value types.

attributes

a Hash where keys are attribute keys

namespace

“” (default namespace) by default

Raises an ArgumentError if any key in the map is not a legal SDL identifier (see SDL4R#validate_identifier), or any value is not a legal SDL type.

Raises:

  • (ArgumentError)


721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
# File 'lib/sdl4r/tag.rb', line 721

def set_attributes(namespace, attribute_hash = nil)
  if attribute_hash.nil?
    attribute_hash, namespace = namespace, ""
  end
  namespace = namespace.id2name if namespace.is_a? Symbol
  
  raise ArgumentError, "namespace can't be nil" if namespace.nil?
  raise ArgumentError, "attribute_hash should be a Hash" unless attribute_hash.is_a? Hash

  namespace_attributes = @attributesByNamespace[namespace]
  namespace_attributes.clear if namespace_attributes
  
  attribute_hash.each_pair do |key, value|
      # Calling set_attribute() is required to ensure validations
      set_attribute(namespace, key, value)
  end
end

#to_child_hashObject

Returns a new Hash where the children’s names as keys and their values as the key’s value. Example:

child1 "toto"
child2 2

would give

{ "child1" => "toto", "child2" => 2 }


451
452
453
454
455
# File 'lib/sdl4r/tag.rb', line 451

def to_child_hash
  hash = {}
  children { |child| hash[child.name] = child.value }
  return hash
end

#to_child_string_hashObject

Returns a new Hash where the children’s names as keys and their values as the key’s value. Values are converted to Strings. nil values become empty Strings. Example:

child1 "toto"
child2 2
child3 null

would give

{ "child1" => "toto", "child2" => "2", "child3" => "" }


469
470
471
472
473
474
475
476
477
# File 'lib/sdl4r/tag.rb', line 469

def to_child_string_hash
  hash = {}
  children do |child|
    # FIXME: it is quite hard to be sure whether we should mimic the Java version
    # as there might be a lot of values that don't translate nicely to Strings.
    hash[child.name] = child.value.to_s
  end
  return hash
end

#to_sObject

Get a String representation of this SDL Tag. This method returns a complete description of the Tag’s state using SDL (i.e. the output can be parsed by #read)

Returns A string representation of this tag using SDL



852
853
854
# File 'lib/sdl4r/tag.rb', line 852

def to_s
  to_string
end

#to_string(line_prefix = "", indent = "\t") ⇒ Object

linePrefix

A prefix to insert before every line.

Returns A string representation of this tag using SDL

TODO: break up long lines using the backslash



861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
# File 'lib/sdl4r/tag.rb', line 861

def to_string(line_prefix = "", indent = "\t")
  line_prefix = "" if line_prefix.nil?
  s = ""
  s << line_prefix
  
  if name == ANONYMOUS_TAG_NAME && namespace.empty?
    skip_value_space = true
  else
    skip_value_space = false
    s << "#{namespace}:" unless namespace.empty?
    s << name
  end

  # output values
  previous_value = nil
  values do |value|
    if skip_value_space
      skip_value_space = false
    else
      s << " "
    end
    if value.is_a?(SdlTimeSpan) and previous_value.is_a?(Date)
      s << value.to_s(true)
    else
      s << SDL4R.format(value, true, line_prefix, indent)
    end
    previous_value = value
  end

  # output attributes
  unless @attributesByNamespace.empty?
    all_attributes_hash = attributes
    all_attributes_array = all_attributes_hash.sort { |a, b|
      namespace1, name1 = a[0].split(':')
      namespace1, name1 = "", namespace1 if name1.nil?
      namespace2, name2 = b[0].split(':')
      namespace2, name2 = "", namespace2 if name2.nil?

      diff = namespace1 <=> namespace2
      diff == 0 ? name1 <=> name2 : diff
    }
    all_attributes_array.each do |attribute_name, attribute_value|
      s << " " << attribute_name << '=' << SDL4R.format(attribute_value, true)
    end
  end

  # output children
  unless @children.empty?
    s << " {#{$/}"
    children_to_string(line_prefix + indent, s)
    s << line_prefix << ?}
  end

  return s
end

#to_xml_string(options = {}) ⇒ Object

Returns a string containing an XML representation of this tag. Values will be represented using _val0, _val1, etc.

options

a hash of the options

options:

:line_prefix

a text prefixing each line (default: “”)

:uri_by_namespace

a Hash giving the URIs for the namespaces

:indent

text specifying one indentation (default: “t”)

:eol

end of line expression (default: “n”)

:omit_null_attributes

if true, null/nil attributes are not exported (default: false). Otherwise, they are exported as follows:

tag attr="null"


965
966
967
968
969
970
971
972
973
974
# File 'lib/sdl4r/tag.rb', line 965

def to_xml_string(options = {})
  options = {
    :uri_by_namespace => nil,
    :indent => "\t",
    :line_prefix => "",
    :eol => "\n",
    :omit_null_attributes => false
  }.merge(options)
  _to_xml_string(options[:line_prefix], options)
end

#valueObject

A convenience method that returns the first value.



298
299
300
# File 'lib/sdl4r/tag.rb', line 298

def value
  @values[0]
end

#value=(value) ⇒ Object

A convenience method that sets the first value in the value list. See # #add_value for legal types.

value

The value to be set.

Raises

ArgumentError

if the value is not a legal SDL type



290
291
292
293
# File 'lib/sdl4r/tag.rb', line 290

def value=(value)
  @values[0] = SDL4R.coerce_or_fail(value)
  nil
end

#valuesObject

Returns an Array of the values of this Tag or enumerates them.

tag.values # => [123, "spices"]
tag.values { |value| puts value }


523
524
525
526
527
528
529
530
# File 'lib/sdl4r/tag.rb', line 523

def values # :yields: value
  if block_given?
    @values.each { |v| yield v }
    nil
  else
    return @values
  end
end

#values=(someValues) ⇒ Object

Set the values for this tag. See #add_value for legal value types.

values

The new values

Raises an ArgumentError if the collection contains any values which are not legal SDL types.



538
539
540
541
542
543
544
545
# File 'lib/sdl4r/tag.rb', line 538

def values=(someValues)
  @values.clear()
  someValues.each { |v|
    # this is required to ensure validation of types
    add_value(v)
  }
  nil
end

#write(output, include_root = false) ⇒ Object

Write this tag out to the given IO or StringIO or String (optionally clipping the root.) Returns output.

output

an IO or StringIO or a String to write to

include_root

if true this tag will be written out as the root element, if false only the

children will be written. False by default.


816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
# File 'lib/sdl4r/tag.rb', line 816

def write(output, include_root = false)
  if output.is_a? String
    io = StringIO.new(output)
    close_io = true # indicates we close the IO ourselves
  elsif output.is_a? IO or output.is_a? StringIO
    io = output
    close_io = false # let the caller close the IO
  else
    raise ArgumentError, "'output' should be a String or an IO but was #{output.class}"
  end
  
  if include_root
    io << to_s
  else
    first = true
    children do |child|
      if first
        first = false
      else
        io << $/
      end
      io << child.to_s
    end
  end
  
  io.close() if close_io

  output
end