class REXML::Element
REXML::Element 对象表示一个 XML 元素。
一个元素
-
有一个名称(字符串)。
-
可能有一个父节点(另一个元素)。
-
有零个或多个子节点(其他元素、文本、CDATA、处理指令和注释)。
-
有零个或多个兄弟节点(其他元素、文本、CDATA、处理指令和注释)。
-
有零个或多个命名属性。
赶时间?¶ ↑
如果您对 XML 有一定的了解,并且心中有一个特定的任务,您可能需要查看任务页面,特别是元素的任务页面。
名称¶ ↑
一个元素有一个名称,该名称在创建元素时最初设置
e = REXML::Element.new('foo') e.name # => "foo"
可以更改名称
e.name = 'bar' e.name # => "bar"
父节点¶ ↑
一个元素可能有一个父节点。
可以在创建元素时显式分配其父节点
e0 = REXML::Element.new('foo') e1 = REXML::Element.new('bar', e0) e1.parent # => <foo> ... </>
注意:元素的表示形式始终显示元素的名称。如果元素有子节点,则表示形式会通过包含省略号 (...
) 来指示。
可以在任何时候显式分配父节点
e2 = REXML::Element.new('baz') e1.parent = e2 e1.parent # => <baz/>
当元素作为子节点添加时,其父节点会自动设置
e1.add_element(e0) e0.parent # => <bar> ... </>
对于没有父节点的元素,方法 parent
返回 nil
。
子节点¶ ↑
一个元素有零个或多个子节点。子节点是所有父节点为元素本身的对象的一个有序集合。
子节点可能包含元素、文本、注释、处理指令和 CDATA 的任意组合。(此示例通过 context
设置控制空格来保持整洁。)
xml_string = <<-EOT <root> <ele_0/> text 0 <!--comment 0--> <?target_0 pi_0?> <![CDATA[cdata 0]]> <ele_1/> text 1 <!--comment 1--> <?target_0 pi_1?> <![CDATA[cdata 1]]> </root> EOT context = {ignore_whitespace_nodes: :all, compress_whitespace: :all} d = REXML::Document.new(xml_string, context) root = d.root root.children.size # => 10 root.each {|child| p "#{child.class}: #{child}" }
输出
"REXML::Element: <ele_0/>" "REXML::Text: \n text 0\n " "REXML::Comment: comment 0" "REXML::Instruction: <?target_0 pi_0?>" "REXML::CData: cdata 0" "REXML::Element: <ele_1/>" "REXML::Text: \n text 1\n " "REXML::Comment: comment 1" "REXML::Instruction: <?target_0 pi_1?>" "REXML::CData: cdata 1"
可以使用继承的方法 Parent#insert_before
或 Parent#insert_after
添加子节点
xml_string = '<root><a/><c/><d/></root>' d = REXML::Document.new(xml_string) root = d.root c = d.root[1] # => <c/> root.insert_before(c, REXML::Element.new('b')) root.to_a # => [<a/>, <b/>, <c/>, <d/>]
可以使用 Parent#replace_child
替换子节点
root.replace_child(c, REXML::Element.new('x')) root.to_a # => [<a/>, <b/>, <x/>, <d/>]
可以使用 Parent#delete
删除子节点
x = root[2] # => <x/> root.delete(x) root.to_a # => [<a/>, <b/>, <d/>]
兄弟节点¶ ↑
一个元素有零个或多个兄弟节点,它们是该元素父节点的其他子节点。
在上面的示例中,元素 ele_1
位于 CDATA 兄弟节点和文本兄弟节点之间
ele_1 = root[5] # => <ele_1/> ele_1.previous_sibling # => "cdata 0" ele_1.next_sibling # => "\n text 1\n "
属性¶ ↑
一个元素有零个或多个命名属性。
一个新元素没有属性
e = REXML::Element.new('foo') e.attributes # => {}
可以添加Attributes
e.add_attribute('bar', 'baz') e.add_attribute('bat', 'bam') e.attributes.size # => 2 e['bar'] # => "baz" e['bat'] # => "bam"
可以修改现有属性
e.add_attribute('bar', 'bad') e.attributes.size # => 2 e['bar'] # => "bad"
可以删除现有属性
e.delete_attribute('bar') e.attributes.size # => 1 e['bar'] # => nil
这里有什么¶ ↑
首先,看看其他地方有什么?
类 REXML::Element 从其祖先类继承
REXML::Element 本身及其祖先还包括模块
创建元素的方法¶ ↑
属性
的方法¶ ↑
- [attribute_name]
-
返回属性值。
add_attribute
-
添加一个新属性。
add_attributes
-
添加多个新属性。
attribute
-
返回给定名称和可选命名空间的属性值。
delete_attribute
-
删除一个属性。
子节点的方法¶ ↑
- [索引]
-
返回给定偏移量的子节点。
add_element
-
将一个元素添加为最后一个子节点。
delete_element
-
删除一个子元素。
each_element
-
使用每个子元素调用给定的块。
each_element_with_attribute
-
使用每个满足给定条件的子元素调用给定的块,这些条件可以包括属性名称。
each_element_with_text
-
使用每个满足给定条件的子元素调用给定的块,这些条件可以包括文本。
get_elements
-
返回与给定 xpath 匹配的子元素数组。
文本子节点的方法¶ ↑
add_text
-
向元素添加一个文本节点。
get_text
-
返回满足指定条件的文本节点。
text
-
从满足指定条件的第一个节点返回文本字符串。
texts
-
返回元素的文本子节点的数组。
text=
-
添加、删除或替换元素的第一个文本子节点
其他子节点的方法¶ ↑
cdatas
-
返回元素的 cdata 子节点的数组。
comments
-
返回元素的注释子节点的数组。
instructions
-
返回元素的指令子节点的数组。
命名空间的方法¶ ↑
add_namespace
-
向元素添加一个命名空间。
delete_namespace
-
从元素中删除一个命名空间。
namespace
-
返回元素的字符串命名空间 URI。
namespaces
-
返回元素中所有已定义的命名空间的哈希值。
prefixes
-
返回元素中所有已定义的命名空间的字符串前缀(名称)的数组
查询的方法¶ ↑
document
-
返回元素所属的文档(如果有)。
root
-
返回元素的最远的元素(非文档)祖先。
root_node
-
返回元素的最远祖先。
xpath
-
返回相对于最远父元素的元素的字符串 xpath
has_attributes?
-
返回元素是否具有属性。
has_elements?
-
返回元素是否具有元素。
has_text?
-
返回元素是否具有文本。
next_element
-
返回下一个作为元素的兄弟节点。
previous_element
-
返回上一个作为元素的兄弟节点。
raw
-
返回是否为元素设置了原始模式。
whitespace
-
返回是否尊重元素的空格。
ignore_whitespace_nodes
-
返回是否忽略元素的空格节点。
node_type
-
返回符号
:element
。
另一个方法¶ ↑
inspect
-
返回元素的字符串表示形式。
访问器¶ ↑
elements
-
返回元素的
REXML::Elements
对象。 attributes
-
返回元素的
REXML::Attributes
对象。 context
-
返回或设置元素的上下文哈希。
常量
- UNDEFINED
属性
用于访问此元素的属性和子元素的机制。
上下文保存有关处理环境的信息,例如空格处理。
用于访问此元素的属性和子元素的机制。
公共类方法
返回一个新的 REXML::Element 对象。
当没有给出参数时,返回名称为 'UNDEFINED'
的元素
e = REXML::Element.new # => <UNDEFINED/> e.class # => REXML::Element e.name # => "UNDEFINED"
当仅给出参数 name
时,返回给定名称的元素
REXML::Element.new('foo') # => <foo/>
当仅给出参数 element
时,它必须是 REXML::Element 对象;返回给定元素的浅拷贝
e0 = REXML::Element.new('foo') e1 = REXML::Element.new(e0) # => <foo/>
当还给出参数 parent
时,它必须是 REXML::Parent
对象
e = REXML::Element.new('foo', REXML::Parent.new) e.parent # => #<REXML::Parent @parent=nil, @children=[<foo/>]>
当还给出参数 context
时,它必须是一个表示元素上下文的哈希;请参阅 元素上下文
e = REXML::Element.new('foo', nil, {raw: :all}) e.context # => {:raw=>:all}
# File rexml-3.4.0/lib/rexml/element.rb, line 319 def initialize( arg = UNDEFINED, parent=nil, context=nil ) super(parent) @elements = Elements.new(self) @attributes = Attributes.new(self) @context = context if arg.kind_of? String self.name = arg elsif arg.kind_of? Element self.name = arg.expanded_name arg.attributes.each_attribute{ |attribute| @attributes << Attribute.new( attribute ) } @context = arg.context end end
公共实例方法
当给出整数参数 index
时,返回偏移量为 index
的子节点,如果没有则返回 nil
d = REXML::Document.new '><root><a/>text<b/>more<c/></root>' root = d.root (0..root.size).each do |index| node = root[index] p "#{index}: #{node} (#{node.class})" end
输出
"0: <a/> (REXML::Element)" "1: text (REXML::Text)" "2: <b/> (REXML::Element)" "3: more (REXML::Text)" "4: <c/> (REXML::Element)" "5: (NilClass)"
当给出字符串参数 attr_name
时,如果给定属性名称存在,则返回其字符串值,否则返回 nil
d = REXML::Document.new('<root attr="value"></root>') root = d.root root['attr'] # => "value" root['nosuch'] # => nil
当给出符号参数 attr_sym
时,返回 [attr_sym.to_s]
root[:attr] # => "value" root[:nosuch] # => nil
# File rexml-3.4.0/lib/rexml/element.rb, line 1246 def [](name_or_index) case name_or_index when String attributes[name_or_index] when Symbol attributes[name_or_index.to_s] else super end end
向此元素添加一个属性,覆盖任何具有相同名称的现有属性。
当给出字符串参数 name
和对象 value
时,添加使用该名称和值创建的属性
e = REXML::Element.new e.add_attribute('attr', 'value') # => "value" e['attr'] # => "value" e.add_attribute('attr', 'VALUE') # => "VALUE" e['attr'] # => "VALUE"
当仅给出属性对象 attribute
时,添加给定的属性
a = REXML::Attribute.new('attr', 'value') e.add_attribute(a) # => attr='value' e['attr'] # => "value" a = REXML::Attribute.new('attr', 'VALUE') e.add_attribute(a) # => attr='VALUE' e['attr'] # => "VALUE"
# File rexml-3.4.0/lib/rexml/element.rb, line 1345 def add_attribute( key, value=nil ) if key.kind_of? Attribute @attributes << key else @attributes[key] = value end end
向元素添加零个或多个属性;返回参数。
如果给出哈希参数 hash
,则每个键都必须是一个字符串;添加使用键/值对创建的每个属性
e = REXML::Element.new h = {'foo' => 'bar', 'baz' => 'bat'} e.add_attributes(h)
如果给出参数 array
,则每个数组元素都必须是一个 2 元素数组 <tt>[name, value];每个名称都必须是一个字符串
e = REXML::Element.new a = [['foo' => 'bar'], ['baz' => 'bat']] e.add_attributes(a)
# File rexml-3.4.0/lib/rexml/element.rb, line 1376 def add_attributes hash if hash.kind_of? Hash hash.each_pair {|key, value| @attributes[key] = value } elsif hash.kind_of? Array hash.each { |value| @attributes[ value[0] ] = value[1] } end end
添加一个子元素,可以选择性地为添加的元素设置属性;返回添加的元素。
如果参数是字符串 name
,则创建一个具有该名称的新元素,并将该新元素作为子元素添加。
e0 = REXML::Element.new('foo') e0.add_element('bar') e0[0] # => <bar/>
如果参数是 name
和哈希参数 attributes
,则在新元素上设置属性。
e0.add_element('baz', {'bat' => '0', 'bam' => '1'}) e0[1] # => <baz bat='0' bam='1'/>
如果参数是元素 element
,则将该元素作为子元素添加。
e0 = REXML::Element.new('foo') e1 = REXML::Element.new('bar') e0.add_element(e1) e0[0] # => <bar/>
如果参数是 element
和哈希参数 attributes
,则在添加的元素上设置属性。
e0.add_element(e1, {'bat' => '0', 'bam' => '1'}) e0[1] # => <bar bat='0' bam='1'/>
# File rexml-3.4.0/lib/rexml/element.rb, line 732 def add_element element, attrs=nil raise "First argument must be either an element name, or an Element object" if element.nil? el = @elements.add(element) attrs.each do |key, value| el.attributes[key]=value end if attrs.kind_of? Hash el end
向元素添加命名空间;返回 self
。
如果只使用参数 prefix
,则使用给定的 prefix
和命名空间 URI 添加命名空间。
e = REXML::Element.new('foo') e.add_namespace('bar') e.namespaces # => {"xmlns"=>"bar"}
如果同时给出参数 prefix
和 uri
,则使用这两个参数添加命名空间。
e.add_namespace('baz', 'bat') e.namespaces # => {"xmlns"=>"bar", "baz"=>"bat"}
# File rexml-3.4.0/lib/rexml/element.rb, line 655 def add_namespace( prefix, uri=nil ) unless uri @attributes["xmlns"] = prefix else prefix = "xmlns:#{prefix}" unless prefix =~ /^xmlns:/ @attributes[ prefix ] = uri end self end
向元素添加文本。
当给出字符串参数 string
时,返回 nil
。
如果元素没有子文本节点,则使用该字符串创建一个 REXML::Text 对象,遵循当前关于空格和原始数据的设置,然后将该节点添加到元素中。
d = REXML::Document.new('<a><b/></a>') a = d.root a.add_text('foo') a.to_a # => [<b/>, "foo"]
如果元素有子文本节点,则将该字符串附加到最后一个文本节点。
d = REXML::Document.new('<a>foo<b/>bar</a>') a = d.root a.add_text('baz') a.to_a # => ["foo", <b/>, "barbaz"] a.add_text('baz') a.to_a # => ["foo", <b/>, "barbazbaz"]
当给出文本节点参数 text_node
时,将该节点作为元素中的最后一个文本节点附加;返回 self
。
d = REXML::Document.new('<a>foo<b/>bar</a>') a = d.root a.add_text(REXML::Text.new('baz')) a.to_a # => ["foo", <b/>, "bar", "baz"] a.add_text(REXML::Text.new('baz')) a.to_a # => ["foo", <b/>, "bar", "baz", "baz"]
# File rexml-3.4.0/lib/rexml/element.rb, line 1147 def add_text( text ) if text.kind_of? String if @children[-1].kind_of? Text @children[-1] << text return end text = Text.new( text, whitespace(), nil, raw() ) end self << text unless text.nil? return self end
返回给定属性名称的字符串值。
如果只给出参数 name
,则返回命名属性的值(如果存在),否则返回 nil
。
xml_string = <<-EOT <root xmlns="ns0"> <a xmlns="ns1" attr="value"></a> <b xmlns="ns2" attr="value"></b> <c attr="value"/> </root> EOT d = REXML::Document.new(xml_string) root = d.root a = root[1] # => <a xmlns='ns1' attr='value'/> a.attribute('attr') # => attr='value' a.attribute('nope') # => nil
如果给出参数 name
和 namespace
,则返回命名属性的值(如果存在),否则返回 nil
。
xml_string = "<root xmlns:a='a' a:x='a:x' x='x'/>" document = REXML::Document.new(xml_string) document.root.attribute("x") # => x='x' document.root.attribute("x", "a") # => a:x='a:x'
# File rexml-3.4.0/lib/rexml/element.rb, line 1287 def attribute( name, namespace=nil ) prefix = namespaces.key(namespace) if namespace prefix = nil if prefix == 'xmlns' ret_val = attributes.get_attribute( prefix ? "#{prefix}:#{name}" : name ) return ret_val unless ret_val.nil? return nil if prefix.nil? # now check that prefix'es namespace is not the same as the # default namespace return nil unless ( namespaces[ prefix ] == namespaces[ 'xmlns' ] ) attributes.get_attribute( name ) end
返回元素 REXML::CData
子元素的冻结数组。
xml_string = <<-EOT <root> <![CDATA[foo]]> <![CDATA[bar]]> </root> EOT d = REXML::Document.new(xml_string) cds = d.root.cdatas # => ["foo", "bar"] cds.frozen? # => true cds.map {|cd| cd.class } # => [REXML::CData, REXML::CData]
# File rexml-3.4.0/lib/rexml/element.rb, line 1420 def cdatas find_all { |child| child.kind_of? CData }.freeze end
返回元素的浅拷贝,其中包含名称和属性,但不包含父元素或子元素。
e = REXML::Element.new('foo') e.add_attributes({'bar' => 0, 'baz' => 1}) e.clone # => <foo bar='0' baz='1'/>
# File rexml-3.4.0/lib/rexml/element.rb, line 383 def clone self.class.new self end
返回元素 REXML::Comment
子元素的冻结数组。
xml_string = <<-EOT <root> <!--foo--> <!--bar--> </root> EOT d = REXML::Document.new(xml_string) cs = d.root.comments cs.frozen? # => true cs.map {|c| c.class } # => [REXML::Comment, REXML::Comment] cs.map {|c| c.to_s } # => ["foo", "bar"]
# File rexml-3.4.0/lib/rexml/element.rb, line 1441 def comments find_all { |child| child.kind_of? Comment }.freeze end
如果存在,则删除命名属性;如果找到,则返回删除的属性,否则返回 nil
。
e = REXML::Element.new('foo') e.add_attribute('bar', 'baz') e.delete_attribute('bar') # => <bar/> e.delete_attribute('bar') # => nil
# File rexml-3.4.0/lib/rexml/element.rb, line 1395 def delete_attribute(key) attr = @attributes.get_attribute(key) attr.remove unless attr.nil? end
删除一个子元素。
当给出基于 1 的整数参数 index
时,如果存在,则删除并返回该偏移量处的子元素;索引不包括文本节点;如果元素不存在,则返回 nil
。
d = REXML::Document.new '<a><b/>text<c/></a>' a = d.root # => <a> ... </> a.delete_element(1) # => <b/> a.delete_element(1) # => <c/> a.delete_element(1) # => nil
当给出元素参数 element
时,如果存在,则删除并返回该子元素,否则返回 nil
。
d = REXML::Document.new '<a><b/>text<c/></a>' a = d.root # => <a> ... </> c = a[2] # => <c/> a.delete_element(c) # => <c/> a.delete_element(c) # => nil
当给出 xpath 参数 xpath
时,如果存在,则删除并返回 xpath 处的元素,否则返回 nil
。
d = REXML::Document.new '<a><b/>text<c/></a>' a = d.root # => <a> ... </> a.delete_element('//c') # => <c/> a.delete_element('//c') # => nil
# File rexml-3.4.0/lib/rexml/element.rb, line 778 def delete_element element @elements.delete element end
从元素中删除一个命名空间。
如果不带参数,则删除默认命名空间。
d = REXML::Document.new "<a xmlns:foo='bar' xmlns='twiddle'/>" d.to_s # => "<a xmlns:foo='bar' xmlns='twiddle'/>" d.root.delete_namespace # => <a xmlns:foo='bar'/> d.to_s # => "<a xmlns:foo='bar'/>"
如果使用参数 namespace
,则删除指定的命名空间。
d.root.delete_namespace('foo') d.to_s # => "<a/>"
如果未找到此类命名空间,则不执行任何操作。
d.root.delete_namespace('nosuch') d.to_s # => "<a/>"
# File rexml-3.4.0/lib/rexml/element.rb, line 687 def delete_namespace namespace="xmlns" namespace = "xmlns:#{namespace}" unless namespace == 'xmlns' attribute = attributes.get_attribute(namespace) attribute.remove unless attribute.nil? self end
如果元素是文档的一部分,则返回该文档。
d = REXML::Document.new('<a><b><c/></b></a>') top_element = d.first child = top_element.first top_element.document == d # => true child.document == d # => true
如果元素不是文档的一部分,则返回 nil
。
REXML::Element.new.document # => nil
对于文档,返回 self
。
d.document == d # => true
# File rexml-3.4.0/lib/rexml/element.rb, line 475 def document rt = root rt.parent if rt end
使用每个子元素调用给定的块。
d = REXML::Document.new '<a><b>b</b><c>b</c><d>d</d><e/></a>' a = d.root a.each_element {|e| p e }
输出
<b> ... </> <c> ... </> <d> ... </> <e/>
# File rexml-3.4.0/lib/rexml/element.rb, line 930 def each_element( xpath=nil, &block ) # :yields: Element @elements.each( xpath, &block ) end
使用符合给定条件的每个子元素调用给定的块。
如果只给出字符串参数 attr_name
,则使用具有该属性的每个子元素调用该块。
d = REXML::Document.new '<a><b id="1"/><c id="2"/><d id="1"/><e/></a>' a = d.root a.each_element_with_attribute('id') {|e| p e }
输出
<b id='1'/> <c id='2'/> <d id='1'/>
如果给出参数 attr_name
和字符串参数 value
,则使用具有该属性且具有该值的每个子元素调用该块。
a.each_element_with_attribute('id', '1') {|e| p e }
输出
<b id='1'/> <d id='1'/>
如果给出参数 attr_name
、value
和整数参数 max
,则最多使用 max
个子元素调用该块。
a.each_element_with_attribute('id', '1', 1) {|e| p e }
输出
<b id='1'/>
如果给出所有参数,包括 xpath
,则只使用符合前三个条件并且还匹配给定 xpath
的子元素调用该块。
a.each_element_with_attribute('id', '1', 2, '//d') {|e| p e }
输出
<d id='1'/>
# File rexml-3.4.0/lib/rexml/element.rb, line 847 def each_element_with_attribute( key, value=nil, max=0, name=nil, &block ) # :yields: Element each_with_something( proc {|child| if value.nil? child.attributes[key] != nil else child.attributes[key]==value end }, max, name, &block ) end
使用符合给定条件的每个子元素调用给定的块。
如果没有参数,则使用每个具有文本的子元素调用该块。
d = REXML::Document.new '<a><b>b</b><c>b</c><d>d</d><e/></a>' a = d.root a.each_element_with_text {|e| p e }
输出
<b> ... </> <c> ... </> <d> ... </>
如果使用单个字符串参数 text
,则使用具有完全相同文本的每个元素调用该块。
a.each_element_with_text('b') {|e| p e }
输出
<b> ... </> <c> ... </>
如果使用参数 text
和整数参数 max
,则最多使用 max
个元素调用该块。
a.each_element_with_text('b', 1) {|e| p e }
输出
<b> ... </>
如果给出所有参数,包括 xpath
,则只使用符合前两个条件并且还匹配给定 xpath
的子元素调用该块。
a.each_element_with_text('b', 2, '//c') {|e| p e }
输出
<c> ... </>
# File rexml-3.4.0/lib/rexml/element.rb, line 904 def each_element_with_text( text=nil, max=0, name=nil, &block ) # :yields: Element each_with_something( proc {|child| if text.nil? child.has_text? else child.text == text end }, max, name, &block ) end
返回与给定 xpath
匹配的元素数组。
xml_string = <<-EOT <root> <a level='1'> <a level='2'/> </a> </root> EOT d = REXML::Document.new(xml_string) d.root.get_elements('//a') # => [<a level='1'> ... </>, <a level='2'/>]
# File rexml-3.4.0/lib/rexml/element.rb, line 949 def get_elements( xpath ) @elements.to_a( xpath ) end
返回指定元素中的第一个文本节点子节点(如果存在),否则返回 nil
。
如果没有参数,则从 self
返回第一个文本节点。
d = REXML::Document.new "<p>some text <b>this is bold!</b> more text</p>" d.root.get_text.class # => REXML::Text d.root.get_text # => "some text "
如果使用参数 xpath
,则从与 xpath
匹配的元素返回第一个文本节点。
d.root.get_text(1) # => "this is bold!"
# File rexml-3.4.0/lib/rexml/element.rb, line 1053 def get_text path = nil rv = nil if path element = @elements[ path ] rv = element.get_text unless element.nil? else rv = @children.find { |node| node.kind_of? Text } end return rv end
如果元素具有属性,则返回 true
,否则返回 false
。
d = REXML::Document.new('<root><a attr="val"/><b/></root>') a, b = *d.root a.has_attributes? # => true b.has_attributes? # => false
# File rexml-3.4.0/lib/rexml/element.rb, line 1315 def has_attributes? return !@attributes.empty? end
如果元素有一个或多个元素子节点,则返回 true
,否则返回 false
。
d = REXML::Document.new '<a><b/>text<c/></a>' a = d.root # => <a> ... </> a.has_elements? # => true b = a[0] # => <b/> b.has_elements? # => false
# File rexml-3.4.0/lib/rexml/element.rb, line 794 def has_elements? !@elements.empty? end
如果元素有一个或多个文本节点,则返回 true
,否则返回 false
。
d = REXML::Document.new '<a><b/>text<c/></a>' a = d.root a.has_text? # => true b = a[0] b.has_text? # => false
# File rexml-3.4.0/lib/rexml/element.rb, line 1002 def has_text? not text().nil? end
如果为元素忽略空格节点,则返回 true
。
请参阅 元素上下文。
# File rexml-3.4.0/lib/rexml/element.rb, line 513 def ignore_whitespace_nodes @ignore_whitespace_nodes = false if @context if @context[:ignore_whitespace_nodes] @ignore_whitespace_nodes = (@context[:ignore_whitespace_nodes] == :all or @context[:ignore_whitespace_nodes].include? expanded_name) end end end
返回元素的字符串表示形式。
对于没有属性且没有子元素的元素,显示元素名称。
REXML::Element.new.inspect # => "<UNDEFINED/>"
显示属性(如果有)。
e = REXML::Element.new('foo') e.add_attributes({'bar' => 0, 'baz' => 1}) e.inspect # => "<foo bar='0' baz='1'/>"
如果有子元素,则显示省略号(...
)。
e.add_element(REXML::Element.new('bar')) e.add_element(REXML::Element.new('baz')) e.inspect # => "<foo bar='0' baz='1'> ... </>"
# File rexml-3.4.0/lib/rexml/element.rb, line 358 def inspect rv = "<#@expanded_name" @attributes.each_attribute do |attr| rv << " " attr.write( rv, 0 ) end if children.size > 0 rv << "> ... </>" else rv << "/>" end end
返回元素 REXML::Instruction
子元素的冻结数组。
xml_string = <<-EOT <root> <?target0 foo?> <?target1 bar?> </root> EOT d = REXML::Document.new(xml_string) is = d.root.instructions is.frozen? # => true is.map {|i| i.class } # => [REXML::Instruction, REXML::Instruction] is.map {|i| i.to_s } # => ["<?target0 foo?>", "<?target1 bar?>"]
# File rexml-3.4.0/lib/rexml/element.rb, line 1462 def instructions find_all { |child| child.kind_of? Instruction }.freeze end
返回元素的字符串命名空间 URI,可能派生自其祖先之一。
xml_string = <<-EOT <root> <a xmlns='1' xmlns:y='2'> <b/> <c xmlns:z='3'/> </a> </root> EOT d = REXML::Document.new(xml_string) b = d.elements['//b'] b.namespace # => "1" b.namespace('y') # => "2" b.namespace('nosuch') # => nil
# File rexml-3.4.0/lib/rexml/element.rb, line 618 def namespace(prefix=nil) if prefix.nil? prefix = prefix() end if prefix == '' prefix = "xmlns" else prefix = "xmlns:#{prefix}" unless prefix[0,5] == 'xmlns' end ns = nil target = self while ns.nil? and target ns = target.attributes[prefix] target = target.parent end ns = '' if ns.nil? and prefix == 'xmlns' return ns end
返回元素及其祖先中所有已定义命名空间的哈希值。
xml_string = <<-EOT <root> <a xmlns:x='1' xmlns:y='2'> <b/> <c xmlns:z='3'/> </a> </root> EOT d = REXML::Document.new(xml_string) d.elements['//a'].namespaces # => {"x"=>"1", "y"=>"2"} d.elements['//b'].namespaces # => {"x"=>"1", "y"=>"2"} d.elements['//c'].namespaces # => {"x"=>"1", "y"=>"2", "z"=>"3"}
# File rexml-3.4.0/lib/rexml/element.rb, line 591 def namespaces namespaces = {} namespaces = parent.namespaces if parent namespaces = namespaces.merge( attributes.namespaces ) return namespaces end
如果存在,则返回下一个兄弟元素,否则返回 nil
。
d = REXML::Document.new '<a><b/>text<c/></a>' d.root.elements['b'].next_element #-> <c/> d.root.elements['c'].next_element #-> nil
# File rexml-3.4.0/lib/rexml/element.rb, line 963 def next_element element = next_sibling element = element.next_sibling until element.nil? or element.kind_of? Element return element end
返回符号 :element
。
d = REXML::Document.new('<a/>') a = d.root # => <a/> a.node_type # => :element
# File rexml-3.4.0/lib/rexml/element.rb, line 1168 def node_type :element end
返回元素及其祖先中所有已定义命名空间的字符串前缀(名称)数组。
xml_string = <<-EOT <root> <a xmlns:x='1' xmlns:y='2'> <b/> <c xmlns:z='3'/> </a> </root> EOT d = REXML::Document.new(xml_string, {compress_whitespace: :all}) d.elements['//a'].prefixes # => ["x", "y"] d.elements['//b'].prefixes # => ["x", "y"] d.elements['//c'].prefixes # => ["x", "y", "z"]
# File rexml-3.4.0/lib/rexml/element.rb, line 565 def prefixes prefixes = [] prefixes = parent.prefixes if parent prefixes |= attributes.prefixes return prefixes end
如果存在,则返回上一个兄弟元素,否则返回 nil
。
d = REXML::Document.new '<a><b/>text<c/></a>' d.root.elements['c'].previous_element #-> <b/> d.root.elements['b'].previous_element #-> nil
# File rexml-3.4.0/lib/rexml/element.rb, line 979 def previous_element element = previous_sibling element = element.previous_sibling until element.nil? or element.kind_of? Element return element end
如果为元素设置了原始模式,则返回 true
。
请参阅 元素上下文。
该评估针对 expanded_name
进行测试,因此对命名空间敏感。
# File rexml-3.4.0/lib/rexml/element.rb, line 533 def raw @raw = (@context and @context[:raw] and (@context[:raw] == :all or @context[:raw].include? expanded_name)) @raw end
返回元素最远的元素(而不是文档)祖先。
d = REXML::Document.new('<a><b><c/></b></a>') top_element = d.first child = top_element.first top_element.root == top_element # => true child.root == top_element # => true
对于文档,返回最顶层的元素。
d.root == top_element # => true
# File rexml-3.4.0/lib/rexml/element.rb, line 443 def root target = self while target return target.elements[1] if target.kind_of? Document parent = target.parent return target if parent.kind_of? Document or parent.nil? target = parent end nil end
返回 self
的最远祖先。
当元素是文档的一部分时,返回文档的根节点。请注意,根节点与文档元素不同;在此示例中,a
是文档元素,根节点是它的父节点。
d = REXML::Document.new('<a><b><c/></b></a>') top_element = d.first # => <a> ... </> child = top_element.first # => <b> ... </> d.root_node == d # => true top_element.root_node == d # => true child.root_node == d # => true
当元素不是文档的一部分,但确实有祖先元素时,返回最远的祖先元素。
e0 = REXML::Element.new('foo') e1 = REXML::Element.new('bar') e1.parent = e0 e2 = REXML::Element.new('baz') e2.parent = e1 e2.root_node == e0 # => true
当元素没有祖先元素时,返回 self
。
e = REXML::Element.new('foo') e.root_node == e # => true
# File rexml-3.4.0/lib/rexml/element.rb, line 422 def root_node parent.nil? ? self : parent.root_node end
返回指定元素中第一个文本节点子节点的文本字符串(如果存在),否则返回 nil
。
如果没有参数,则从 self
中的第一个文本节点返回文本。
d = REXML::Document.new "<p>some text <b>this is bold!</b> more text</p>" d.root.text.class # => String d.root.text # => "some text "
如果使用参数 xpath
,则从与 xpath
匹配的元素中的第一个文本节点返回文本。
d.root.text(1) # => "this is bold!"
请注意,一个元素可能具有多个文本节点,这些文本节点可能被其他非文本子节点分隔开,如上所示。即便如此,返回的值也是来自第一个此类节点的字符串文本。
另请注意,文本注释是通过方法 get_text
检索的,因此始终是规范化的文本。
# File rexml-3.4.0/lib/rexml/element.rb, line 1030 def text( path = nil ) rv = get_text(path) return rv.value unless rv.nil? nil end
添加、替换或删除元素中的第一个文本节点子节点。
如果使用字符串参数 string
,则创建一个包含该字符串的新 REXML::Text 节点,遵循当前关于空格和行的设置,然后将该节点作为元素中的第一个文本子节点放置;返回 string
。
如果元素没有文本子节点,则添加文本节点。
d = REXML::Document.new '<a><b/></a>' d.root.text = 'foo' #-> '<a><b/>foo</a>'
如果元素有文本子节点,则替换它。
d.root.text = 'bar' #-> '<a><b/>bar</a>'
如果使用参数 nil
,则删除第一个文本子节点。
d.root.text = nil #-> '<a><b/><c/></a>'
# File rexml-3.4.0/lib/rexml/element.rb, line 1089 def text=( text ) if text.kind_of? String text = Text.new( text, whitespace(), nil, raw() ) elsif !text.nil? and !text.kind_of? Text text = Text.new( text.to_s, whitespace(), nil, raw() ) end old_text = get_text if text.nil? old_text.remove unless old_text.nil? else if old_text.nil? self << text else old_text.replace_with( text ) end end return self end
返回该元素的 REXML::Text
子元素的冻结数组
xml_string = '<root><a/>text<b/>more<c/></root>' d = REXML::Document.new(xml_string) ts = d.root.texts ts.frozen? # => true ts.map {|t| t.class } # => [REXML::Text, REXML::Text] ts.map {|t| t.to_s } # => ["text", "more"]
# File rexml-3.4.0/lib/rexml/element.rb, line 1478 def texts find_all { |child| child.kind_of? Text }.freeze end
如果此元素保留空格,则返回 true
,否则返回 false
。
请参阅 元素上下文。
该评估会针对元素的 expanded_name
进行测试,因此是区分命名空间的。
# File rexml-3.4.0/lib/rexml/element.rb, line 490 def whitespace @whitespace = nil if @context if @context[:respect_whitespace] @whitespace = (@context[:respect_whitespace] == :all or @context[:respect_whitespace].include? expanded_name) end @whitespace = false if (@context[:compress_whitespace] and (@context[:compress_whitespace] == :all or @context[:compress_whitespace].include? expanded_name) ) end @whitespace = true unless @whitespace == false @whitespace end
已弃用¶ ↑
输出此元素,并递归输出所有子元素。
- output
-
输出一个支持“<< string”的对象;这是
document will be written.
- indent
-
一个整数。 如果为 -1,则不使用缩进;否则,缩进将为此空格数,并且子元素将额外缩进。 默认为 -1
- transitive
-
如果 transitive 为 true 并且 indent >= 0,则输出将以美观打印的方式进行,这样添加的空格不会影响文档的解析树
- ie_hack
-
此 hack 在空标签上的 /> 前插入一个空格,以解决 Internet Explorer 的一个限制。默认为 false
out = '' doc.write( out ) #-> doc is written to the string 'out' doc.write( $stdout ) #-> doc written to the console
# File rexml-3.4.0/lib/rexml/element.rb, line 1504 def write(output=$stdout, indent=-1, transitive=false, ie_hack=false) Kernel.warn("#{self.class.name}.write is deprecated. See REXML::Formatters", uplevel: 1) formatter = if indent > -1 if transitive require_relative "formatters/transitive" REXML::Formatters::Transitive.new( indent, ie_hack ) else REXML::Formatters::Pretty.new( indent, ie_hack ) end else REXML::Formatters::Default.new( ie_hack ) end formatter.write( self, output ) end
返回相对于最远父元素的元素的字符串 xpath
d = REXML::Document.new('<a><b><c/></b></a>') a = d.root # => <a> ... </> b = a[0] # => <b> ... </> c = b[0] # => <c/> d.xpath # => "" a.xpath # => "/a" b.xpath # => "/a/b" c.xpath # => "/a/b/c"
如果没有父节点,则返回元素的扩展名称
e = REXML::Element.new('foo') e.xpath # => "foo"
# File rexml-3.4.0/lib/rexml/element.rb, line 1192 def xpath path_elements = [] cur = self path_elements << __to_xpath_helper( self ) while cur.parent cur = cur.parent path_elements << __to_xpath_helper( cur ) end return path_elements.reverse.join( "/" ) end
私有实例方法
# File rexml-3.4.0/lib/rexml/element.rb, line 1521 def __to_xpath_helper node rv = node.expanded_name.clone if node.parent results = node.parent.find_all {|n| n.kind_of?(REXML::Element) and n.expanded_name == node.expanded_name } if results.length > 1 idx = results.index( node ) rv << "[#{idx+1}]" end end rv end
一个私有辅助方法
# File rexml-3.4.0/lib/rexml/element.rb, line 1536 def each_with_something( test, max=0, name=nil ) num = 0 @elements.each( name ){ |child| yield child if test.call(child) and num += 1 return if max>0 and num == max } end