module saxophonit
import sax
-intrude import standard::file
+intrude import core::file
private import reader_model
private import lexer
#
# Also note that this XML processor is unable to retrieve a file from an URL
# (only local paths are supported).
+#
+# Usage example:
+#
+# # Retrieve all text nodes.
+# class TextListener
+# super ContentHandler
+# #
+# private var buf: Buffer = new FlatBuffer
+# private var sp: Bool = false
+# #
+# redef fun characters(str: String) do
+# if sp then
+# if buf.length > 0 then buf.append(" ")
+# sp = false
+# end
+# buf.append(str)
+# end
+# #
+# redef fun ignorable_whitespace(str: String) do
+# sp = true
+# end
+# #
+# # Return the concatenation of all text nodes.
+# redef fun to_s do return buf.to_s
+# end
+# #
+# var text = new TextListener
+# var reader = new XophonReader
+# #
+# reader.content_handler = text
+# reader.parse(new InputSource.with_stream(new StringReader("<foo>bar baz <n>42</n>.</foo>")))
+# assert text.to_s == "bar baz 42."
class XophonReader
super XMLReader
private var model = new XophonReaderModel
private var lexer: XophonLexer is noinit
- redef fun entity_resolver: nullable EntityResolver do return model.entity_resolver
- redef fun entity_resolver=(entity_resolver: nullable EntityResolver) do
+ redef fun entity_resolver do return model.entity_resolver
+ redef fun entity_resolver=(entity_resolver) do
model.entity_resolver = entity_resolver
end
- redef fun dtd_handler: nullable DTDHandler do return model.dtd_handler
- redef fun dtd_handler=(dtd_handler: nullable DTDHandler) do
+ redef fun dtd_handler do return model.dtd_handler
+ redef fun dtd_handler=(dtd_handler) do
model.dtd_handler = dtd_handler
end
- redef fun content_handler: nullable ContentHandler do return model.content_handler
- redef fun content_handler=(content_handler: nullable ContentHandler) do
+ redef fun content_handler do return model.content_handler
+ redef fun content_handler=(content_handler) do
model.content_handler = content_handler
end
- redef fun error_handler: nullable ErrorHandler do return model.error_handler
- redef fun error_handler=(error_handler: nullable ErrorHandler) do
+ redef fun error_handler do return model.error_handler
+ redef fun error_handler=(error_handler) do
model.error_handler = error_handler
end
- redef fun feature_recognized(name: String): Bool do
+ redef fun feature_recognized(name) do
return model.feature_recognized(name)
end
- redef fun feature_readable(name: String): Bool do
+ redef fun feature_readable(name) do
return model.feature_readable(name)
end
- redef fun feature_writable(name: String): Bool do
+ redef fun feature_writable(name) do
return model.feature_readable(name)
end
- redef fun feature(name: String): Bool do return model.feature(name)
- redef fun feature=(name: String, value: Bool) do model.feature(name) = value
+ redef fun feature(name) do return model.feature(name)
+ redef fun feature=(name, value) do model.feature(name) = value
- redef fun property_recognized(name: String): Bool do
+ redef fun property_recognized(name) do
return model.property_recognized(name)
end
- redef fun property_readable(name: String): Bool do
+ redef fun property_readable(name) do
return model.property_readable(name)
end
- redef fun property_writable(name: String): Bool do
+ redef fun property_writable(name) do
return model.property_writable(name)
end
- redef fun property(name: String): nullable Object do
+ redef fun property(name) do
return model.property(name)
end
- redef fun property=(name: String, value: nullable Object) do
+ redef fun property=(name, value) do
model.property(name) = value
end
- redef fun parse(input: InputSource) do
- var stream: IStream
+ redef fun parse(input) do
var system_id: nullable MaybeError[String, Error] = null
model.locator = new SAXLocatorImpl
model.fire_fatal_error("File <{input.system_id.as(not null)}> not found.", null)
else
lexer = new XophonLexer(model,
- new IFStream.open(system_id.value))
+ new FileReader.open(system_id.value))
parse_main
lexer.close
end
end
end
- redef fun parse_file(system_id: String) do
+ redef fun parse_file(system_id) do
parse(new InputSource.with_system_id(system_id))
end
# Expect a `document` production.
private fun expect_document: Bool do
- var success = true
var got_doctype = false
var got_element = false
var buffer: Buffer = new FlatBuffer
# Number of consecutive closing brackets.
- var closing: Int = 0
+ var closing = 0
if lexer.expect_string("CDATA[",
" at the beginning of a CDATA section.") then
if lexer.accept('#') then
if lexer.accept('x') then
if lexer.expect_hex(ref) then
- buffer.chars.add(ref.to_hex.ascii)
+ buffer.chars.add(ref.to_hex.code_point)
return lexer.expect(';', "")
else
return lexer.fire_unexpected_char(
". Expecting an hexadecimal digit")
end
else if lexer.accept_digits(ref) then
- buffer.chars.add(ref.to_i.ascii)
+ buffer.chars.add(ref.to_i.code_point)
return lexer.expect(';', "")
else
return lexer.fire_unexpected_char(" in a character reference. " +