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



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

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



128
129
130
# File 'lib/rexml/doctype.rb', line 128

def context
  @parent.context
end

#entity(name) ⇒ Object



132
133
134
# File 'lib/rexml/doctype.rb', line 132

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



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

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



172
173
174
# File 'lib/rexml/doctype.rb', line 172

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



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

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



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

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



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/rexml/doctype.rb', line 108

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