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_CHAR, XMLTokens::NAME_START_CHAR, 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.



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
69
# File 'lib/rexml/doctype.rb', line 42

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



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

def entities
  @entities
end

#external_idObject (readonly)

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



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

def external_id
  @external_id
end

#nameObject (readonly)

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



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

def name
  @name
end

#namespacesObject (readonly)

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



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

def namespaces
  @namespaces
end

Instance Method Details

#add(child) ⇒ Object



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

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



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

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



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

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



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

def clone
  DocType.new self
end

#contextObject



135
136
137
138
139
140
141
# File 'lib/rexml/doctype.rb', line 135

def context
  if @parent
    @parent.context
  else
    nil
  end
end

#entity(name) ⇒ Object



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

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

#node_typeObject



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

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



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

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



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

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



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

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



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

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 indentation will be used; otherwise, the indentation will be this number of spaces, and children will be indented an additional amount.

transitive

Ignored

ie_hack

Ignored



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/rexml/doctype.rb', line 109

def write( output, indent=0, transitive=false, ie_hack=false )
  f = REXML::Formatters::Default.new
  c = context
  if c and c[:prologue_quote] == :apostrophe
    quote = "'"
  else
    quote = "\""
  end
  indent( output, indent )
  output << START
  output << ' '
  output << @name
  output << " #{@external_id}" if @external_id
  output << " #{quote}#{@long_name}#{quote}" if @long_name
  output << " #{quote}#{@uri}#{quote}" if @uri
  unless @children.empty?
    output << ' ['
    @children.each { |child|
      output << "\n"
      f.write( child, output )
    }
    output << "\n]"
  end
  output << STOP
end