Skip to content

foxy_xml_events ​

FoXy streaming parser: the document as a sequence of events, reported to a handler of yours.

Extend xml_handler, override the callbacks you need (each one does nothing by default) and call parse on a string or a file: the callbacks come in source order (start_element, characters, end_element, ...), the source is read in chunks and the memory used does not depend on its size. The callbacks are ordinary procedures (they may write files, print, keep any state in your type).

@note The pure tokenizer drives an event_builder, which queues the events of one chunk; parse then decodes them and calls the handler. Character data (and CDATA) is reported in pieces, decoded (references, line ends), never splitting a reference, a CR LF pair or a UTF-8 character; attribute values are normalized and decoded as xml_file%attribute returns them. Elements are always balanced: an element closed implicitly (malformed input, or open at the source end) gets its end_element. Problems are reported in source order among the other events; a problem inside character data may come between two pieces of that text (where depends on the chunks).

Source: src/lib/foxy_xml_events.f90

Dependencies

Contents ​

Variables ​

NameTypeAttributesDescription
DEFAULT_CHUNKinteger(kind=I8P)parameterDefault size of the chunks read (1 MiB).
MAX_REFERENCEinteger(kind=I8P)parameterLongest reference start kept for the next piece.
EVENT_STARTinteger(kind=I4P)parameterA start tag (with its attributes).
EVENT_ENDinteger(kind=I4P)parameterAn end tag (or the end of a self closing tag).
EVENT_TEXTinteger(kind=I4P)parameterCharacter data, raw.
EVENT_CDATAinteger(kind=I4P)parameterCDATA content, raw.
EVENT_COMMENTinteger(kind=I4P)parameterA comment, whole.
EVENT_PIinteger(kind=I4P)parameterA processing instruction, whole.
EVENT_DOCTYPEinteger(kind=I4P)parameterA declaration (DOCTYPE), whole.
EVENT_PROBLEMinteger(kind=I4P)parameterA problem of malformed input.

Derived Types ​

xml_attribute ​

An attribute of a start element: its name, as written, and its value, normalized and decoded.

Components ​

NameTypeAttributesDescription
namecharacter(len=:)allocatableName (prefix included).
valuecharacter(len=:)allocatableValue (blanks as spaces, references decoded).

xml_handler ​

Handler of the events of a document: extend it, override the callbacks you need, call parse.

Attributes: abstract

Components ​

NameTypeAttributesDescription
levelinteger(kind=I4P)Depth of the current element (1 for the root), set by parse.
posinteger(kind=I8P)Position (byte) in the source of the current event, set by parse.
is_stoppedlogicalstop_parsing was called.

Type-Bound Procedures ​

NameAttributesDescription
start_elementpass(self)A start tag, with its attributes.
end_elementpass(self)An end tag (also right after a self closing start tag).
characterspass(self)Character data, decoded (maybe in pieces).
cdatapass(self)CDATA content, literal (maybe in pieces).
commentpass(self)A comment, without its markup.
processing_instructionpass(self)A processing instruction: target and data.
doctypepass(self)A declaration (DOCTYPE), as in the source.
problempass(self)A problem of malformed input, with its line.
parsepass(self)Parse a string or a file, calling the callbacks.
stop_parsingpass(self)No more callbacks: parse returns.

event_record ​

An event of the queue.

Components ​

NameTypeAttributesDescription
kindinteger(kind=I4P)Event kind, EVENT_*.
levelinteger(kind=I4P)Element depth.
posinteger(kind=I8P)Position in the source.
namecharacter(len=:)allocatableElement name (start, end), or the message (problem).
textcharacter(len=:)allocatableRaw text (character data, CDATA, comment, PI, declaration).
attributestype(xml_attribute)allocatableAttributes (start).

event_builder ​

Builder queuing the events of one chunk (pure, as the tokenizer requires).

Inheritance

Extends: xml_builder

Components ​

NameTypeAttributesDescription
is_stoppedlogicalSet by the builder to stop the tokenizer (checked after each complete start or end tag).
sanitizelogicalTrim leading and trailing spaces of attribute values.
eventstype(event_record)allocatableEvents queued.
neinteger(kind=I4P)Number of events queued.
open_namecharacter(len=:)allocatableName of the start tag being read.
open_posinteger(kind=I8P)Its position.
open_levelinteger(kind=I4P)Its level.
open_attributestype(xml_attribute)allocatableIts attributes.
nainteger(kind=I4P)Number of its attributes.
stack_idinteger(kind=I4P)allocatableIDs of the open elements.
stack_nametype(xml_attribute)allocatableNames of the open elements (in name).
depthinteger(kind=I4P)Number of open elements.
in_cdatalogicalA CDATA section continues in the next piece.
markup_kindinteger(kind=I4P)Kind of the comment/PI being collected, 0 if none.
markupcharacter(len=:)allocatableComment/PI being collected.
markup_posinteger(kind=I8P)Its position.

Type-Bound Procedures ​

NameAttributesDescription
start_tagpass(self)A start tag begins.
attributepass(self)An attribute of the current start tag.
start_tag_endpass(self)The current start tag is complete.
end_tagpass(self)An open tag is closed by its end tag.
datapass(self)Character data or other markup.
problempass(self)A problem of malformed input.
finishpass(self)The source is ended.

text_decoder ​

Decoder of character data (or CDATA) given in pieces: a final part that may continue in the next piece (a reference without its ;, a CR, an incomplete UTF-8 character) is carried.

Components ​

NameTypeAttributesDescription
carrycharacter(len=:)allocatableRaw characters carried.
posinteger(kind=I8P)Position of the first character carried.
is_cdatalogicalCDATA: references are not decoded.

Subroutines ​

start_element ​

A start tag, with its attributes (in source order, values normalized and decoded); does nothing unless overridden.

fortran
subroutine start_element(self, name, attributes)

Arguments

NameTypeIntentAttributesDescription
selfclass(xml_handler)inoutHandler.
namecharacter(len=*)inElement name, as written.
attributestype(xml_attribute)inAttributes, size 0 if none.

Call graph

end_element ​

An end tag (also right after a self closing start tag); does nothing unless overridden.

fortran
subroutine end_element(self, name)

Arguments

NameTypeIntentAttributesDescription
selfclass(xml_handler)inoutHandler.
namecharacter(len=*)inElement name, as written.

Call graph

characters ​

Character data, decoded; the text between two tags may come in pieces (never splitting a reference or a UTF-8 character); does nothing unless overridden.

fortran
subroutine characters(self, text)

Arguments

NameTypeIntentAttributesDescription
selfclass(xml_handler)inoutHandler.
textcharacter(len=*)inText.

Call graph

cdata ​

CDATA content, literal (line ends normalized), maybe in pieces; does nothing unless overridden.

fortran
subroutine cdata(self, text)

Arguments

NameTypeIntentAttributesDescription
selfclass(xml_handler)inoutHandler.
textcharacter(len=*)inText.

Call graph

comment ​

A comment, without <!-- and -->; does nothing unless overridden.

fortran
subroutine comment(self, text)

Arguments

NameTypeIntentAttributesDescription
selfclass(xml_handler)inoutHandler.
textcharacter(len=*)inComment.

Call graph

processing_instruction ​

A processing instruction <?target data?> (the XML declaration included); does nothing unless overridden.

fortran
subroutine processing_instruction(self, target, data)

Arguments

NameTypeIntentAttributesDescription
selfclass(xml_handler)inoutHandler.
targetcharacter(len=*)inTarget.
datacharacter(len=*)inData, after the blanks following the target.

Call graph

doctype ​

A declaration (<!DOCTYPE ...>), as in the source; does nothing unless overridden.

fortran
subroutine doctype(self, text)

Arguments

NameTypeIntentAttributesDescription
selfclass(xml_handler)inoutHandler.
textcharacter(len=*)inDeclaration.

Call graph

problem ​

A problem of malformed input, as line N: ...; parsing goes on; does nothing unless overridden.

fortran
subroutine problem(self, message)

Arguments

NameTypeIntentAttributesDescription
selfclass(xml_handler)inoutHandler.
messagecharacter(len=*)inProblem description.

Call graph

stop_parsing ​

Stop parsing: no more callbacks, the rest of the source is not read, parse returns.

fortran
subroutine stop_parsing(self)

Arguments

NameTypeIntentAttributesDescription
selfclass(xml_handler)inoutHandler.

parse ​

Parse a string or a file, calling the callbacks of the handler in source order.

@note iostat is 0, the runtime I/O error code if the file cannot be read, or XML_MALFORMED if the input is malformed (every problem is also passed to problem; parsing is tolerant); iomsg holds the first problem, as line N: .... Stopped by stop_parsing, parse returns the problems met so far.

fortran
subroutine parse(self, string, filename, chunk_size, sanitize_attributes_value, iostat, iomsg)

Arguments

NameTypeIntentAttributesDescription
selfclass(xml_handler)inoutHandler.
stringcharacter(len=*)inoptionalSource string.
filenamecharacter(len=*)inoptionalSource file name.
chunk_sizeinteger(kind=I8P)inoptionalSize of the chunks (default 1 MiB).
sanitize_attributes_valuelogicalinoptionalTrim the spaces around values (default true).
iostatinteger(kind=I4P)outoptionalIO status.
iomsgcharacter(len=*)inoutoptionalIO message.

Call graph

dispatch ​

Call the handler for the events queued, then empty the queue.

@note A module procedure with explicit arguments, not an internal procedure of parse: nvfortran 26.9 gives stale values of host-associated variables there.

fortran
subroutine dispatch(self, builder, text_dec, cdata_dec, window, offset, lines, first_problem, is_last, is_file, chunk, unit, string, encoding)

Arguments

NameTypeIntentAttributesDescription
selfclass(xml_handler)inoutHandler.
buildertype(event_builder)inoutEvent builder.
text_dectype(text_decoder)inoutDecoder of character data.
cdata_dectype(text_decoder)inoutDecoder of CDATA.
windowcharacter(len=*)inWindow fed.
offsetinteger(kind=I8P)inPosition of the character before the window.
linesinteger(kind=I8P)inNew lines before the window.
first_problemcharacter(len=:)inoutallocatableFirst problem, located.
is_lastlogicalinThe source ended.
is_filelogicalinThe source is a file.
chunkinteger(kind=I8P)inSize of the chunks.
unitinteger(kind=I4P)inUnit of the source file (if a file).
stringcharacter(len=*)inoptionalSource string.
encodingtype(source_encoding)inEncoding of the source.

Call graph

add_text ​

Add a raw piece of text to a decoder.

Attributes: pure

fortran
subroutine add_text(decoder, raw, pos)

Arguments

NameTypeIntentAttributesDescription
decodertype(text_decoder)inoutDecoder.
rawcharacter(len=*)inRaw piece.
posinteger(kind=I8P)inIts position.

Call graph

flush_text ​

Pass to the handler the decoded text of a decoder: all of it if is_final, otherwise all but a final part that may continue in the next piece (a reference without ;, a CR, an incomplete UTF-8 character).

fortran
subroutine flush_text(self, decoder, is_final)

Arguments

NameTypeIntentAttributesDescription
selfclass(xml_handler)inoutHandler.
decodertype(text_decoder)inoutDecoder.
is_finallogicalinThe text is complete.

Call graph

push_event ​

Queue an event.

Attributes: pure

fortran
subroutine push_event(self, kind, level, pos, name, text)

Arguments

NameTypeIntentAttributesDescription
selfclass(event_builder)inoutEvent builder.
kindinteger(kind=I4P)inEvent kind.
levelinteger(kind=I4P)inElement depth.
posinteger(kind=I8P)inPosition.
namecharacter(len=*)inoptionalElement name, or message.
textcharacter(len=*)inoptionalRaw text.

Call graph

pop_element ​

Close the innermost open element: queue its end event.

Attributes: pure

fortran
subroutine pop_element(self, pos)

Arguments

NameTypeIntentAttributesDescription
selfclass(event_builder)inoutEvent builder.
posinteger(kind=I8P)inPosition of the end.

Call graph

queue_start ​

Queue the start event of the start tag read (with its attributes).

Attributes: pure

fortran
subroutine queue_start(self)

Arguments

NameTypeIntentAttributesDescription
selfclass(event_builder)inoutEvent builder.

Call graph

events_start_tag ​

A start tag begins: its attributes follow.

Attributes: pure

fortran
subroutine events_start_tag(self, id, parent_id, level, name, start)

Arguments

NameTypeIntentAttributesDescription
selfclass(event_builder)inoutEvent builder.
idinteger(kind=I4P)inTag ID.
parent_idinteger(kind=I4P)inParent tag ID.
levelinteger(kind=I4P)inTag level.
namecharacter(len=*)inTag name.
startinteger(kind=I8P)inPosition of <.

events_attribute ​

An attribute of the current start tag: normalized and decoded.

Attributes: pure

fortran
subroutine events_attribute(self, id, name, value)

Arguments

NameTypeIntentAttributesDescription
selfclass(event_builder)inoutEvent builder.
idinteger(kind=I4P)inTag ID.
namecharacter(len=*)inAttribute name.
valuecharacter(len=*)inAttribute value, as in the source.

Call graph

events_start_tag_end ​

The current start tag is complete: queue its start (and, if self closing, its end).

Attributes: pure

fortran
subroutine events_start_tag_end(self, id, start, open_end, is_self_closing)

Arguments

NameTypeIntentAttributesDescription
selfclass(event_builder)inoutEvent builder.
idinteger(kind=I4P)inTag ID.
startinteger(kind=I8P)inPosition of <.
open_endinteger(kind=I8P)inPosition of >.
is_self_closinglogicalinThe tag is self closing.

Call graph

events_end_tag ​

An open tag is closed by its end tag: queue the end of the inner open elements (closed implicitly), then its own.

Attributes: pure

fortran
subroutine events_end_tag(self, id, start, open_end, end_start, end_end)

Arguments

NameTypeIntentAttributesDescription
selfclass(event_builder)inoutEvent builder.
idinteger(kind=I4P)inTag ID.
startinteger(kind=I8P)inPosition of the start tag <.
open_endinteger(kind=I8P)inPosition of the start tag >.
end_startinteger(kind=I8P)inPosition of the end tag <.
end_endinteger(kind=I8P)inPosition of the end tag >.

Call graph

events_data ​

Character data or other markup: text and CDATA queued as they come (CDATA without its markup), comments and PIs collected whole, declarations queued.

Attributes: pure

fortran
subroutine events_data(self, kind, chars, first)

Arguments

NameTypeIntentAttributesDescription
selfclass(event_builder)inoutEvent builder.
kindinteger(kind=I4P)inData kind, DATA_*.
charscharacter(len=*)inCharacters, as in the source.
firstinteger(kind=I8P)inPosition of the first character.

Call graph

close_markup ​

Queue the comment or PI collected, if it is complete (or, with is_final, as it is: unterminated).

Attributes: pure

fortran
subroutine close_markup(self, is_final)

Arguments

NameTypeIntentAttributesDescription
selfclass(event_builder)inoutEvent builder.
is_finallogicalinThe source ended.

Call graph

events_problem ​

A problem of malformed input: queued (every one, in order).

Attributes: pure

fortran
subroutine events_problem(self, pos, message)

Arguments

NameTypeIntentAttributesDescription
selfclass(event_builder)inoutEvent builder.
posinteger(kind=I8P)inPosition of the problem.
messagecharacter(len=*)inProblem description.

Call graph

events_finish ​

The source is ended: a start tag not completed, a comment/PI not terminated and the open elements are closed.

Attributes: pure

fortran
subroutine events_finish(self)

Arguments

NameTypeIntentAttributesDescription
selfclass(event_builder)inoutEvent builder.

Call graph

Functions ​

adjustl_blanks ​

Return a text without its leading XML blanks.

Attributes: pure

Returns: character(len=:)

fortran
function adjustl_blanks(text) result(adjusted)

Arguments

NameTypeIntentAttributesDescription
textcharacter(len=*)inText.

Call graph

lines_to ​

Return the line of a position of an open stream file, counting its new lines (positioned reads, in chunks).

Returns: integer(kind=I8P)

fortran
function lines_to(unit, pos, chunk) result(line)

Arguments

NameTypeIntentAttributesDescription
unitinteger(kind=I4P)inFile unit.
posinteger(kind=I8P)inPosition.
chunkinteger(kind=I8P)inSize of the chunks read.

Call graph

count_new_lines ​

Return the number of new lines of a text.

Attributes: pure

Returns: integer(kind=I8P)

fortran
function count_new_lines(text) result(n)

Arguments

NameTypeIntentAttributesDescription
textcharacter(len=*)inText.

Call graph