class REXML::Attributes

一个定义 Attributes 集合的类,该集合属于 Element,并提供用于访问该集合中元素的操作。

公共类方法

new(element) 点击切换源代码

创建并返回一个新的 REXML::Attributes 对象。参数 element 给出的元素会被存储,但其自身的属性不会被修改

ele = REXML::Element.new('foo')
attrs = REXML::Attributes.new(ele)
attrs.object_id == ele.attributes.object_id # => false

REXML::Attributes 类中的其他实例方法可能会引用

  • element.document.

  • element.prefix.

  • element.expanded_name.

# File rexml-3.4.0/lib/rexml/element.rb, line 2156
def initialize element
  @element = element
end

公共实例方法

<<( attribute )
别名:add
[name] → attribute_value 或 nil 点击切换源代码

返回 name 给定的属性的值,如果存在;否则返回 nil。返回的值是未规范化的属性值,其中实体已展开

xml_string = <<-EOT
  <root xmlns:foo="http://foo" xmlns:bar="http://bar">
     <ele foo:att='1' bar:att='2' att='&lt;'/>
  </root>
EOT
d = REXML::Document.new(xml_string)
ele = d.elements['//ele'] # => <a foo:att='1' bar:att='2' att='&lt;'/>
ele.attributes['att']     # => "<"
ele.attributes['bar:att'] # => "2"
ele.attributes['nosuch']  # => nil

相关:get_attribute(返回一个 Attribute 对象)。

# File rexml-3.4.0/lib/rexml/element.rb, line 2181
def [](name)
  attr = get_attribute(name)
  return attr.value unless attr.nil?
  return nil
end
[name] = value → value 点击切换源代码

valuenil 时,将其赋值给给定 name 的属性,如果存在,则覆盖先前的值

xml_string = <<-EOT
  <root xmlns:foo="http://foo" xmlns:bar="http://bar">
     <ele foo:att='1' bar:att='2' att='&lt;'/>
  </root>
EOT
d = REXML::Document.new(xml_string)
ele = d.root.elements['//ele'] # => <a foo:att='1' bar:att='2' att='&lt;'/>
attrs = ele.attributes
attrs['foo:att'] = '2' # => "2"
attrs['baz:att'] = '3' # => "3"

valuenil 时,如果属性存在则删除该属性

attrs['baz:att'] = nil
attrs.include?('baz:att') # => false
# File rexml-3.4.0/lib/rexml/element.rb, line 2365
def []=( name, value )
  if value.nil?             # Delete the named attribute
    attr = get_attribute(name)
    delete attr
    return
  end

  unless value.kind_of? Attribute
    if @element.document and @element.document.doctype
      value = Text::normalize( value, @element.document.doctype )
    else
      value = Text::normalize( value, nil )
    end
    value = Attribute.new(name, value)
  end
  value.element = @element
  old_attr = fetch(value.name, nil)
  if old_attr.nil?
    store(value.name, value)
  elsif old_attr.kind_of? Hash
    old_attr[value.prefix] = value
  elsif old_attr.prefix != value.prefix
    store value.name, {old_attr.prefix => old_attr,
                       value.prefix    => value}
  else
    store value.name, value
  end
  return @element
end
add(attribute) → attribute 点击切换源代码

添加属性 attribute,如果存在,则替换同名的先前属性;返回 attribute

xml_string = <<-EOT
  <root xmlns:foo="http://foo" xmlns:bar="http://bar">
     <ele foo:att='1' bar:att='2' att='&lt;'/>
  </root>
EOT
d = REXML::Document.new(xml_string)
ele = d.root.elements['//ele'] # => <a foo:att='1' bar:att='2' att='&lt;'/>
attrs = ele.attributes
attrs # => {"att"=>{"foo"=>foo:att='1', "bar"=>bar:att='2', ""=>att='&lt;'}}
attrs.add(REXML::Attribute.new('foo:att', '2')) # => foo:att='2'
attrs.add(REXML::Attribute.new('baz', '3')) # => baz='3'
attrs.include?('baz') # => true
# File rexml-3.4.0/lib/rexml/element.rb, line 2522
def add( attribute )
  self[attribute.name] = attribute
end
别名:<<
delete(name) → element 点击切换源代码
delete(attribute) → element

删除指定的属性(如果存在);返回属性的元素。

当给出字符串参数 name 时,如果存在,则删除该名称的属性

xml_string = <<-EOT
  <root xmlns:foo="http://foo" xmlns:bar="http://bar">
     <ele foo:att='1' bar:att='2' att='&lt;'/>
  </root>
EOT
d = REXML::Document.new(xml_string)
ele = d.root.elements['//ele'] # => <a foo:att='1' bar:att='2' att='&lt;'/>
attrs = ele.attributes
attrs.delete('foo:att') # => <ele bar:att='2' att='&lt;'/>
attrs.delete('foo:att') # => <ele bar:att='2' att='&lt;'/>

当给出属性参数 attribute 时,如果存在,则删除该属性

attr = REXML::Attribute.new('bar:att', '2')
attrs.delete(attr) # => <ele att='&lt;'/> # => <ele att='&lt;'/>
attrs.delete(attr) # => <ele att='&lt;'/> # => <ele/>
调用超类方法
# File rexml-3.4.0/lib/rexml/element.rb, line 2475
def delete( attribute )
  name = nil
  prefix = nil
  if attribute.kind_of? Attribute
    name = attribute.name
    prefix = attribute.prefix
  else
    attribute =~ Namespace::NAMESPLIT
    prefix, name = $1, $2
    prefix = '' unless prefix
  end
  old = fetch(name, nil)
  if old.kind_of? Hash # the supplied attribute is one of many
    old.delete(prefix)
    if old.size == 1
      repl = nil
      old.each_value{|v| repl = v}
      store name, repl
    end
  elsif old.nil?
    return @element
  else # the supplied attribute is a top-level one
    super(name)
  end
  @element
end
delete_all(name) → array_of_removed_attributes 点击切换源代码

删除所有与给定 name 匹配的属性;返回已删除属性的数组

xml_string = <<-EOT
  <root xmlns:foo="http://foo" xmlns:bar="http://bar">
     <ele foo:att='1' bar:att='2' att='&lt;'/>
  </root>
EOT
d = REXML::Document.new(xml_string)
ele = d.root.elements['//ele'] # => <a foo:att='1' bar:att='2' att='&lt;'/>
attrs = ele.attributes
attrs.delete_all('att') # => [att='&lt;']
# File rexml-3.4.0/lib/rexml/element.rb, line 2544
def delete_all( name )
  rv = []
  each_attribute { |attribute|
    rv << attribute if attribute.expanded_name == name
  }
  rv.each{ |attr| attr.remove }
  return rv
end
each {|expanded_name, value| ... } 点击切换源代码

使用每个展开的名称/值对调用给定的块

xml_string = <<-EOT
  <root xmlns:foo="http://foo" xmlns:bar="http://bar">
     <ele foo:att='1' bar:att='2' att='&lt;'/>
  </root>
EOT
d = REXML::Document.new(xml_string)
ele = d.root.elements['//ele']   # => <a foo:att='1' bar:att='2' att='&lt;'/>
ele.attributes.each do |expanded_name, value|
  p [expanded_name, value]
end

输出

["foo:att", "1"]
["bar:att", "2"]
["att", "<"]
# File rexml-3.4.0/lib/rexml/element.rb, line 2283
def each
  return to_enum(__method__) unless block_given?
  each_attribute do |attr|
    yield [attr.expanded_name, attr.value]
  end
end
each_attribute {|attr| ... } 点击切换源代码

使用每个 REXML::Attribute 对象调用给定的块

xml_string = <<-EOT
  <root xmlns:foo="http://foo" xmlns:bar="http://bar">
     <ele foo:att='1' bar:att='2' att='&lt;'/>
  </root>
EOT
d = REXML::Document.new(xml_string)
ele = d.root.elements['//ele']   # => <a foo:att='1' bar:att='2' att='&lt;'/>
ele.attributes.each_attribute do |attr|
  p [attr.class, attr]
end

输出

[REXML::Attribute, foo:att='1']
[REXML::Attribute, bar:att='2']
[REXML::Attribute, att='&lt;']
# File rexml-3.4.0/lib/rexml/element.rb, line 2250
def each_attribute # :yields: attribute
  return to_enum(__method__) unless block_given?
  each_value do |val|
    if val.kind_of? Attribute
      yield val
    else
      val.each_value { |atr| yield atr }
    end
  end
end
get_attribute(name) → attribute_object 或 nil 点击切换源代码

返回给定 name 的 REXML::Attribute 对象

xml_string = <<-EOT
  <root xmlns:foo="http://foo" xmlns:bar="http://bar">
     <ele foo:att='1' bar:att='2' att='&lt;'/>
  </root>
EOT
d = REXML::Document.new(xml_string)
ele = d.root.elements['//ele'] # => <a foo:att='1' bar:att='2' att='&lt;'/>
attrs = ele.attributes
attrs.get_attribute('foo:att')       # => foo:att='1'
attrs.get_attribute('foo:att').class # => REXML::Attribute
attrs.get_attribute('bar:att')       # => bar:att='2'
attrs.get_attribute('att')           # => att='&lt;'
attrs.get_attribute('nosuch')        # => nil
# File rexml-3.4.0/lib/rexml/element.rb, line 2309
def get_attribute( name )
  attr = fetch( name, nil )
  if attr.nil?
    return nil if name.nil?
    # Look for prefix
    name =~ Namespace::NAMESPLIT
    prefix, n = $1, $2
    if prefix
      attr = fetch( n, nil )
      # check prefix
      if attr == nil
      elsif attr.kind_of? Attribute
        return attr if prefix == attr.prefix
      else
        attr = attr[ prefix ]
        return attr
      end
    end
    element_document = @element.document
    if element_document and element_document.doctype
      expn = @element.expanded_name
      expn = element_document.doctype.name if expn.size == 0
      attr_val = element_document.doctype.attribute_of(expn, name)
      return Attribute.new( name, attr_val ) if attr_val
    end
    return nil
  end
  if attr.kind_of? Hash
    attr = attr[ @element.prefix ]
  end
  return attr
end
get_attribute_ns(namespace, name) 点击切换源代码

返回属性中与给定的 namespacename 匹配的 REXML::Attribute 对象

xml_string = <<-EOT
  <root xmlns:foo="http://foo" xmlns:bar="http://bar">
     <ele foo:att='1' bar:att='2' att='&lt;'/>
  </root>
EOT
d = REXML::Document.new(xml_string)
ele = d.root.elements['//ele'] # => <a foo:att='1' bar:att='2' att='&lt;'/>
attrs = ele.attributes
attrs.get_attribute_ns('http://foo', 'att')    # => foo:att='1'
attrs.get_attribute_ns('http://foo', 'nosuch') # => nil
# File rexml-3.4.0/lib/rexml/element.rb, line 2570
def get_attribute_ns(namespace, name)
  result = nil
  each_attribute() { |attribute|
    if name == attribute.name &&
      namespace == attribute.namespace() &&
      ( !namespace.empty? || !attribute.fully_expanded_name.index(':') )
      # foo will match xmlns:foo, but only if foo isn't also an attribute
      result = attribute if !result or !namespace.empty? or
                            !attribute.fully_expanded_name.index(':')
    end
  }
  result
end
length 点击切换源代码

返回属性的数量

xml_string = <<-EOT
  <root xmlns:foo="http://foo" xmlns:bar="http://bar">
     <ele foo:att='1' bar:att='2' att='&lt;'/>
  </root>
EOT
d = REXML::Document.new(xml_string)
ele = d.root.elements['//ele']   # => <a foo:att='1' bar:att='2' att='&lt;'/>
ele.attributes.length # => 3
# File rexml-3.4.0/lib/rexml/element.rb, line 2221
def length
  c = 0
  each_attribute { c+=1 }
  c
end
别名:size
namespaces 点击切换源代码

返回命名空间的名称/值对的哈希

xml_string = '<a xmlns="foo" xmlns:x="bar" xmlns:y="twee" z="glorp"/>'
d = REXML::Document.new(xml_string)
d.root.attributes.namespaces # => {"xmlns"=>"foo", "x"=>"bar", "y"=>"twee"}
# File rexml-3.4.0/lib/rexml/element.rb, line 2431
def namespaces
  namespaces = {}
  each_attribute do |attribute|
    namespaces[attribute.name] = attribute.value if attribute.prefix == 'xmlns' or attribute.name == 'xmlns'
  end
  if @element.document and @element.document.doctype
    expn = @element.expanded_name
    expn = @element.document.doctype.name if expn.size == 0
    @element.document.doctype.attributes_of(expn).each {
      |attribute|
      namespaces[attribute.name] = attribute.value if attribute.prefix == 'xmlns' or attribute.name == 'xmlns'
    }
  end
  namespaces
end
prefixes → array_of_prefix_strings 点击切换源代码

返回属性中前缀字符串的数组。如果存在,该数组不包含默认的命名空间声明。

xml_string = '<a xmlns="foo" xmlns:x="bar" xmlns:y="twee" z="glorp"/>'
d = REXML::Document.new(xml_string)
d.root.attributes.prefixes # => ["x", "y"]
# File rexml-3.4.0/lib/rexml/element.rb, line 2406
def prefixes
  ns = []
  each_attribute do |attribute|
    ns << attribute.name if attribute.prefix == 'xmlns'
  end
  if @element.document and @element.document.doctype
    expn = @element.expanded_name
    expn = @element.document.doctype.name if expn.size == 0
    @element.document.doctype.attributes_of(expn).each {
      |attribute|
      ns << attribute.name if attribute.prefix == 'xmlns'
    }
  end
  ns
end
size()
别名:length
to_a → array_of_attribute_objects 点击切换源代码

返回表示属性的 REXML::Attribute 对象数组

xml_string = <<-EOT
  <root xmlns:foo="http://foo" xmlns:bar="http://bar">
     <ele foo:att='1' bar:att='2' att='&lt;'/>
  </root>
EOT
d = REXML::Document.new(xml_string)
ele = d.root.elements['//ele']   # => <a foo:att='1' bar:att='2' att='&lt;'/>
attrs = ele.attributes.to_a      # => [foo:att='1', bar:att='2', att='&lt;']
attrs.first.class                # => REXML::Attribute
# File rexml-3.4.0/lib/rexml/element.rb, line 2203
def to_a
  enum_for(:each_attribute).to_a
end