9. Robust input and text
Case files are written by hand, and hands make mistakes. broken.xml forgets an end tag:
xml
<case name="cavity">
<time>
<dt unit="s">1.0e-3</dt>
<steps>500
</time>
</case>f90
program solver
!< Tutorial, chapter 9: robust input and text.
use foxy
implicit none
type(xml_file) :: case_file
integer(I4P) :: iostat
character(len=256) :: iomsg
call case_file%parse(filename='broken.xml', iostat=iostat, iomsg=iomsg)
if (iostat==XML_MALFORMED) print '(A)', 'broken.xml: '//trim(iomsg)
print '(A)', 'dt is still read: '//case_file%content('dt') ! tolerant: the document is built anyway
call case_file%parse(filename='case.xml')
print '(A)', 'notes: '//case_file%content('notes') ! references decoded, CDATA literal
print '(A)', 'escape: '//xml_escape('a < b & "c"')
print '(A)', 'raw: '//xml_unescape('1 < 2 & été')
call case_file%parse(string='<p>the <b>lid</b> moves at <v>1</v> m/s</p>')
print '(A)', 'mixed: '//case_file%content('p') ! the direct text of p, children excluded
print '(A)', case_file%stringify() ! written back as it was
endprogram solver- Parsing is tolerant: the document is built as far as possible, and
iostat=XML_MALFORMEDwithiomsgreports the first problem and its line. Besides the tags structure, FoXy reports invalid names, duplicate attributes, text outside the root element, more root elements, an empty source, ill-formed UTF-8, malformed references (a bare&, ), and an encoding it does not read or that contradicts the byte order mark. - Sources in UTF-16, UTF-32, ISO-8859-1 or windows-1252 are converted to UTF-8 as they are read: everything you get back, and
save, is UTF-8 (Encodings). - Stored text is the source text:
stringifywrites back what was read. The accessors decode it: references (&,é) become characters, CDATA sections are literal, comments are skipped, line ends are LF. xml_escapeandxml_unescapeconvert text yourself; content set withset_contentorxml_tag(content=)is not escaped (it may hold markup), so escape user data first.- Mixed content (text around child tags) is kept:
contentreturns the direct text of a tag, without its children.
Running it
$ solver
broken.xml: line 5: end tag </time> closes open tag <steps>
dt is still read: 1.0e-3
notes: Lid-driven cavity & inflow, after <paper ref="1">.
escape: a < b & "c"
raw: 1 < 2 & été
mixed: the moves at m/s
<p>the <b>lid</b> moves at <v>1</v> m/s</p>What you learned
Check iostat/iomsg of parse; read text through the accessors, escape what you write as content. Reference: Parsing.
This is the end of the tutorial: the cookbook has short recipes for everyday tasks, the reference every method.