class

Mica::XML::Reader

Inherits Mica::Core::LineTracking < Mica::Core::TextInput < Mica::Core::ByteInput < Reference < Object

A pull parser that walks an XML document one node at a time.

The API mirrors stdlib XML::Reader, so code written against it ports by changing the constant. It parses XML 1.0 (5th edition) and XML 1.1 (2nd edition, chosen by the document's declaration) with Namespaces in XML, checks well-formedness as it goes, and raises Mica::ParseError (with line, column and byte offset) at the first error instead of recovering.

reader = Mica::XML::Reader.new(%(<message lang="en">Hello XML!</message>))
reader.read
reader.name    # => "message"
reader["lang"] # => "en"
reader.read
reader.value # => "Hello XML!"

Built from an IO, the reader streams: it keeps one buffer that holds the current token, so memory stays flat on large documents.

Every read draws on a Core::WorkMeter (from ParserOptions#work_budget, or one passed in), so the work done stays linear in the bytes read; see ParserOptions.

WARNING: This type is not concurrency-safe.

Constants

NORMALIZATION_OPERATIONS_PER_BYTE = 8

Operations charged per byte checked for full normalization: the NFC quick check, and for "maybe" results a decomposition and recomposition.

TILDE_OVERLAY = "̴"
XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace"
XMLNS_NAMESPACE = "http://www.w3.org/2000/xmlns/"
YPOGEGRAMMENI = "ͅ"

U+0345 has class 240 and U+0334 class 1: canonical ordering moves the first after, or the second before, any character of class 2 to 239.

Constructors

new(string : String, options : ParserOptions = ParserOptions.default, meter : Core::WorkMeter | Nil = nil, *, name_seed : UInt32 | Nil = nil) : self

Creates a reader over string. The string's bytes are read in place.

Source
new(bytes : Bytes, options : ParserOptions = ParserOptions.default, meter : Core::WorkMeter | Nil = nil, *, name_seed : UInt32 | Nil = nil)

Creates a reader over bytes (UTF-8, or UTF-16 with a byte order mark). The bytes are read in place and must not change while the reader is in use. meter lets several operations share one budget; without it the reader starts a meter from options.work_budget.

name_seed (:nodoc:, for reproducible tests and fuzzing) fixes the name table's hash seed; leave it nil in production so each reader draws a random seed.

Source
new(io : IO, options : ParserOptions = ParserOptions.default, meter : Core::WorkMeter | Nil = nil, *, name_seed : UInt32 | Nil = nil)

Creates a streaming reader over io.

Source

Instance methods

[](name : String) : String

Returns the value of the attribute named name on the current element. Raises KeyError when it is missing.

Source
[]?(name : String) : String | Nil

Returns the value of the attribute named name, or nil.

Source
attributes_count

Returns the number of attributes on the current element.

Source
column_number

Returns the column of the current read position (1-based, characters).

Source
depth

Returns the depth of the current node (the root element is at 0).

Source
empty_element?

Returns true when the current element was written <name/>.

Source
encoding

Returns the encoding the document was decoded from ("UTF-8", "UTF-16", "ISO-8859-1" or "US-ASCII").

Source
expand

Parses the current element's subtree into a new Mica::XML::Document and returns that subtree's element.

NOTE: Unlike libxml2, the reader streams, so expanding consumes the subtree: afterwards the reader sits on the element's END_ELEMENT and the next read moves past it.

Source
has_attributes?

Returns true when the current element has attributes (namespace declarations count, as in libxml2).

Source
internal_subset

Returns the raw internal DTD subset, if any.

Source
line_number

Returns the line of the current read position (1-based).

Source
local_name

Returns the local part of the current element or attribute name (the same as name for other nodes).

Without namespace processing a name is one unit: local_name is the whole name and prefix is nil.

Source
meter

Returns the work meter this reader charges.

Source
move_to_attribute(name : String) : Bool

Moves to the attribute named name (its qualified name).

Source
move_to_element

Moves from an attribute back to its element.

Source
move_to_first_attribute

Moves to the first attribute of the current element.

Source
move_to_next_attribute

Moves to the next attribute of the current element.

Source
name

Returns the qualified name of the current node: the element or attribute name, the PI target, the DOCTYPE root name or the entity name; #text, #cdata-section or #comment for character nodes.

Source
namespace_uri

Returns the namespace URI of the current element or attribute, or nil when it is in no namespace.

Source
next

Skips the current node's subtree and moves to the node after it.

Source
next_sibling

Moves to the next sibling of the current node. Returns false when the parent ends first.

Source
node_type

Returns the type of the node the reader is positioned on.

Source
operations

Returns the operations charged to this reader's meter so far.

Source
options

Returns the options this reader enforces.

Source
position

Returns the current read position (line, column and byte offset). Asking after every event stays linear overall (see Core::LineTracking); the counting is charged to the work meter.

Source
prefix

Returns the namespace prefix of the current element or attribute, or nil when it has none.

Source
public_id

Returns the public identifier of the DOCTYPE, if any.

Source
read

Moves to the next node. Returns false at the end of the document.

Raises Mica::ParseError when the document is not well-formed and Mica::LimitExceededError (including Mica::WorkBudgetExceededError and Mica::DeadlineExceededError) when a limit trips.

Source
read_inner_xml

Returns the markup of the current element's children. Consumes the subtree like expand.

Source
read_outer_xml

Returns the markup of the current element and its children. Consumes the subtree like expand.

Source
renew_meter(budget : Core::WorkBudget = @options.work_budget) : Core::WorkMeter

Replaces the work meter with a fresh one for budget: the operation count and the deadline start again from now. Long-lived streams (a protocol session over a socket) call this between messages instead of disabling the budget.

Source
standalone?

Returns true when the XML declaration says standalone="yes".

Source
system_id

Returns the system identifier of the DOCTYPE, if any. It is never fetched.

Source
value

Returns the text of the current node: character data, comment text, PI data, or the current attribute's normalized value. Returns an empty string for other node types.

Source
xml_version

Returns the version from the XML declaration ("1.0" when absent).

Source

Nested types