Class: REXML::DocType

Inherits:
Parent show all
Includes:
XMLTokens
Defined in:
lib/rexml/doctype.rb

Overview

Represents an XML DOCTYPE declaration; that is, the contents of <!DOCTYPE … >. DOCTYPES can be used to declare the DTD of a document, as well as being used to declare entities used in the document.

Constant Summary collapse

START =
"<!DOCTYPE"
STOP =
">"
SYSTEM =
"SYSTEM"
PUBLIC =
"PUBLIC"
DEFAULT_ENTITIES =
{ 
  'gt'=>EntityConst::GT, 
  'lt'=>EntityConst::LT, 
  'quot'=>EntityConst::QUOT, 
  "apos"=>EntityConst::APOS 
}

Constants included from XMLTokens

XMLTokens::NAME, XMLTokens::NAMECHAR, XMLTokens::NAME_STR, XMLTokens::NCNAME_STR, XMLTokens::NMTOKEN, XMLTokens::NMTOKENS, XMLTokens::REFERENCE

Instance Attribute Summary collapse

Attributes inherited from Child

#parent

Instance Method Summary collapse

Methods inherited from Parent

#[], #[]=, #deep_clone, #delete, #delete_at, #delete_if, #each, #each_index, #index, #insert_after, #insert_before, #parent?, #replace_child, #size, #to_a, #unshift

Methods inherited from Child

#bytes, #document, #next_sibling=, #previous_sibling=, #remove, #replace_with

Methods included from Node

#each_recursive, #find_first_recursive, #indent, #index_in_parent, #next_sibling_node, #parent?, #previous_sibling_node, #to_s

Constructor Details

#initialize(first, parent = nil) ⇒ DocType

Constructor

dt = DocType.new( 'foo', '-//I/Hate/External/IDs' )
# <!DOCTYPE foo '-//I/Hate/External/IDs'>
dt = DocType.new( doctype_to_clone )
# Incomplete.  Shallow clone of doctype

Note that the constructor:

Doctype.new( Source.new( "<!DOCTYPE foo 'bar'>" ) )

is deprecated. Do not use it. It will probably disappear.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/rexml/doctype.rb', line 41

def initialize( first, parent=nil )
  @entities = DEFAULT_ENTITIES
  @long_name = @uri = nil
  if first.kind_of? String
    super()
    @name = first
    @external_id = parent
  elsif first.kind_of? DocType
    super( parent )
    @name = first.name
    @external_id = first.external_id
  elsif first.kind_of? Array
    super( parent )
    @name = first[0]
    @external_id = first[1]
    @long_name = first[2]
    @uri = first[3]
  elsif first.kind_of? Source
    super( parent )
    parser = Parsers::BaseParser.new( first )
    event = parser.pull
    if event[0] == :start_doctype
      @name, @external_id, @long_name, @uri, = event[1..-1]
    end
  else
    super()
  end
end

Instance Attribute Details

#entitiesObject (readonly)

name is the name of the doctype external_id is the referenced DTD, if given



27
28
29
# File 'lib/rexml/doctype.rb', line 27

def entities
  @entities
end

#external_idObject (readonly)

name is the name of the doctype external_id is the referenced DTD, if given



27
28
29
# File 'lib/rexml/doctype.rb', line 27

def external_id
  @external_id
end

#nameObject (readonly)

name is the name of the doctype external_id is the referenced DTD, if given



27
28
29
# File 'lib/rexml/doctype.rb', line 27

def name
  @name
end

#namespacesObject (readonly)

name is the name of the doctype external_id is the referenced DTD, if given



27
28
29
# File 'lib/rexml/doctype.rb', line 27

def namespaces
  @namespaces
end

Instance Method Details

#add(child) ⇒ Object



146
147
148
149
150
# File 'lib/rexml/doctype.rb', line 146

def add child
  super(child)
  @entities = DEFAULT_ENTITIES.clone if @entities == DEFAULT_ENTITIES
  @entities[ child.name ] = child if child.kind_of? Entity
end

#attribute_of(element, attribute) ⇒ Object



84
85
86
87
88
89
90
91
92
# File 'lib/rexml/doctype.rb', line 84

def attribute_of element, attribute
  att_decl = find do |child|
    child.kind_of? AttlistDecl and
    child.element_name == element and
    child.include? attribute
  end
  return nil unless att_decl
  att_decl[attribute]
end

#attributes_of(element) ⇒ Object



74
75
76
77
78
79
80
81
82
# File 'lib/rexml/doctype.rb', line 74

def attributes_of element
  rv = []
  each do |child|
    child.each do |key,val|
      rv << Attribute.new(key,val)
    end if child.kind_of? AttlistDecl and child.element_name == element
  end
  rv
end

#cloneObject



94
95
96
# File 'lib/rexml/doctype.rb', line 94

def clone
  DocType.new self
end

#contextObject



138
139
140
# File 'lib/rexml/doctype.rb', line 138

def context
  @parent.context
end

#entity(name) ⇒ Object



142
143
144
# File 'lib/rexml/doctype.rb', line 142

def entity( name )
  @entities[name].unnormalized if @entities[name]
end

#node_typeObject



70
71
72
# File 'lib/rexml/doctype.rb', line 70

def node_type
  :doctype
end

#notation(name) ⇒ Object

Retrieves a named notation. Only notations declared in the internal DTD subset can be retrieved.

Method contributed by Henrik Martensson



190
191
192
193
194
# File 'lib/rexml/doctype.rb', line 190

def notation(name)
  notations.find { |notation_decl|
    notation_decl.name == name
  }
end

#notationsObject

This method returns a list of notations that have been declared in the internal DTD subset. Notations in the external DTD subset are not listed.

Method contributed by Henrik Martensson



182
183
184
# File 'lib/rexml/doctype.rb', line 182

def notations
  children().select {|node| node.kind_of?(REXML::NotationDecl)}
end

#publicObject

This method retrieves the public identifier identifying the document’s DTD.

Method contributed by Henrik Martensson



156
157
158
159
160
161
162
163
# File 'lib/rexml/doctype.rb', line 156

def public
  case @external_id
  when "SYSTEM"
    nil
  when "PUBLIC"
    strip_quotes(@long_name)
  end
end

#systemObject

This method retrieves the system identifier identifying the document’s DTD

Method contributed by Henrik Martensson



168
169
170
171
172
173
174
175
# File 'lib/rexml/doctype.rb', line 168

def system
  case @external_id
  when "SYSTEM"
    strip_quotes(@long_name)
  when "PUBLIC"
    @uri.kind_of?(String) ? strip_quotes(@uri) : nil
  end
end

#write(output, indent = 0, transitive = false, ie_hack = false) ⇒ Object

output

Where to write the string

indent

An integer. If -1, no indenting will be used; otherwise, the indentation will be this number of spaces, and children will be indented an additional amount.

transitive

If transitive is true and indent is >= 0, then the output will be pretty-printed in such a way that the added whitespace does not affect the absolute value of the document – that is, it leaves the value and number of Text nodes in the document unchanged.

ie_hack

Internet Explorer is the worst piece of crap to have ever been written, with the possible exception of Windows itself. Since IE is unable to parse proper XML, we have to provide a hack to generate XML that IE’s limited abilities can handle. This hack inserts a space before the /> on empty tags.



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/rexml/doctype.rb', line 116

def write( output, indent=0, transitive=false, ie_hack=false )
  indent( output, indent )
  output << START
  output << ' '
  output << @name
  output << " #@external_id" if @external_id
  output << " #@long_name" if @long_name
  output << " #@uri" if @uri
  unless @children.empty?
    next_indent = indent + 1
    output << ' ['
    child = nil    # speed
    @children.each { |child|
      output << "\n"
      child.write( output, next_indent )
    }
    #output << '   '*next_indent
    output << "\n]"
  end
  output << STOP
end