FLEXML(1)
π FLEXML(1) π
okay bestie, sit down, hydrate, because today we're learning FLEXML(1) β the little tool that reads a DTD and hands you back a whole validating XML processor, no cap. perl people made it, it lives in the User Contributed Perl Documentation section, and it's about to be your new obsession. π«Ά
β¨ NAME β¨
flexml β generate validating XML processor and applications from DTD π
π SYNOPSIS π
flexml [-ASHDvdnLXV] [-sskel] [-ppubid] [-iinit_header] [-uuri]
[-rrootags] [-aactions] name[.dtd]
π¦ DESCRIPTION π¦
so here's the vibe: Flexml reads name.dtd, which has to be a DTD (Document Type Definition) describing the format of XML (Extensible Markup Language) documents, and it produces a "validating" XML processor with an interface to support XML applications. and if you want, it can generate proper applications out of special "action files" β either for linking, or textually combined with the processor. iconic behavior. β¨
the generated processor is picky on purpose: it will only validate documents that conform strictly to the DTD, without extending it. more precisely, in practice we restrict XML rule [28] down to
[28r] doctypedecl ::= '<!DOCTYPE' S Name S ExternalID S? '>'
where the ExternalId denotes the used DTD. (one might say, in fact, that flexml implements "non-extensible" markup. :) β yes that's the author's own little joke, we love a self-aware king π)
the generated processor is a flex(1) scanner, by default named name.l, with a corresponding C header file name.h so you can compile generated applications separately. optionally, flexml takes an actions file with per-element actions and produces a C file with element functions for an XML application, with entry points called from the XML processor. (it can also fold the XML application into the XML processor to make stand-alone XML applications β but heads up bestie, that prevents sharing of the processor between applications. π)
and because the author is organized: in "OPTIONS" we list the possible options, in "ACTION FILE FORMAT" we explain how to write applications, in "COMPILATION" we explain how to compile produced processors and applications into executables, and in "BUGS" we list the current limitations of the system before giving standard references. a full itinerary, we love a tour. π§
πΈ OPTIONS πΈ
Flexml takes the following options. every single one, bestie, let's go:
--stand-alone,-Aβ generate a stand-alone scanner application. if you combine it with-aactionsthen the application will be named asactionswith the extension replaced by.l; otherwise it'll be inname.l. Conflicts with-S,-H, and-D. pick a struggle, not all of them π--actions actions,-a actionsβ uses the actions file to produce an XML application in the file with the same name asactions, after replacing the extension with.c. if you combine it with-Athen instead the stand-alone application will include the action functions.--dummy [app_name],-D [app_name]β generate a dummy application with just empty functions, the ones that get called by the XML processor. ifapp_nameisn't specified on the command line, it defaults toname-dummy.c. if you combine it with-a actionsthen the application will insert the specified actions and be named asactionswith the extension replaced by.c. Conflicts with-A; and it's implied by-aunless either of-SHDis specified.--debug,-dβ turns on debug mode in the flex scanner, and also prints out the details of the DTD analysis performed by flexml. detective mode π--header [header_name],-H [header_name]β generate the header file. ifheader_nameisn't specified on the command line, it defaults toname.h. Conflicts with-A; on by default if none of-SHDis specified.--lineno,-Lβ makes the XML processor (as produced byflex(1)) count the lines in the input and keep it available to XML application actions in the integeryylineno. (this one is off by default, because the performance overhead is significant. respect the cost, bestie π)--quiet,-qβ prevents the XML processor (as produced byflex(1)) from reporting the error it runs into onstderr. instead, you'll have to pool for error messages yourself with theparse_err_msg()function. by default, error messages are written onstderr, so this one is very much a choose-your-own-adventure.--dry-run,-nβ "dry-run": do not produce any of the output files. all vibes, zero artifacts. π--pubid pubid,-p pubidβ sets the document type to be "PUBLIC" with the identifierpubidinstead of "SYSTEM", which is the default.--init_header init_header,-i init_headerβ puts a line containing#include "init_header"in the%{...%}section at the top of the generated.lfile. this may be useful for making various flex#defines, for exampleYY_INPUTorYY_DECL.--sysid=sysidβ overrides the "SYSTEM" id of the accepted DTD. sometimes useful when your dtd is placed in a subdirectory. (yes, this one is written with the=and everything, we don't argue with the syntax π)--root-tags roottags,-r roottagsβ restricts the XML processor to validate only documents with one of the root elements listed in the comma-separatedroottags.--scanner [scanner_name],-S [scanner_name]β generate the scanner. ifscanner_nameis not given on the command line, it defaults toname.l. Conflicts with-A; on by default if none of-SHDis specified.--skel skel,-s skelβ use the skeleton scannerskelinstead of the default.--act-bin flexml-act,-T flexml-actβ this is an internal option, mainly used to test versions of flexml that aren't installed yet. insider business π΅οΈ--stack-increment stack_increment,-b stack_incrementβ sets theFLEXML_BUFFERSTACKSIZEtostack_increment(which is100000by default). this controls how much the data stack grows in eachrealloc().--tag-prefix STRING,-O STRINGβ useSTRINGto differentiate multiple versions of flexml in the same C code, just like the-Pflex argument.--uri uri,-u uriβ sets the URI of the DTD, used in the "DOCTYPE" header, to the specifieduri(the default is the DTD name).--verbose,-vβ be verbose: echo each DTD declaration (after parameter expansion).--version,-Vβ print the version of flexml and exit. the shortest conversation in the whole page π
π§ ACTION FILE FORMAT π§
Action files, which you pass to the -a option, are XML documents conforming to the DTD flexml-act.dtd, which is exactly this, and yes we're keeping it verbatim because precision is the moment:
<!ELEMENT actions ((top|start|end)*,main?)>
<!ENTITY % C-code "(#PCDATA)">
<!ELEMENT top %C-code;>
<!ELEMENT start %C-code;> <!ATTLIST start tag NMTOKEN #REQUIRED>
<!ELEMENT end %C-code;> <!ATTLIST end tag NMTOKEN #REQUIRED>
<!ELEMENT main %C-code;>
The elements should be used as follows:
top
Use for top-level C code such as global declarations, utility functions, etc. your little global-zone bestie. π
start
Attaches the code as an action to the element with the name of the required tag attribute. the %C-code; component should be C code suitable for inclusion in a C block (i.e., within {...} so it may contain local variables); furthermore the following extensions are available:
{attribute}β can be used to access the value of the attribute as set withattribute="value"in the start tag. in C,{attribute}will be interpreted depending on the declaration of the attribute. if the attribute is declared as an enumerated type like
<!ATTLIST attrib (alt1 | alt2 |...) ...>
then the C attribute value is of an enumerated type, with the elements written {attribute=alt1}, {attribute=alt2}, etc.; furthermore an unset attribute has the value {!attribute}. if the attribute is not an enumeration then {attribute} is a null-terminated C string (of type char*) and {!attribute} is NULL.
end
Similarly attaches the code as an action to the end tag with the name of the required tag attribute; also here the %C-code; component should be C code suitable for inclusion in a C block. in case the element has "Mixed" contents β i.e., was declared to permit #PCDATA β then the following variable is available:
{#PCDATA}β contains the text (#PCDATA) of the element as a null-terminated C string (of typechar*). in case the Mixed contents element actually mixed text and child elements, thenpcdatacontains the plain concatenation of the text fragments as one string. glue it together, bestie π«Ά
main
Finally, an optional main element can contain the C main function of the XML application. normally the main function should include (at least) one call of the XML processor:
yylex()β invokes the XML processor produced byflex(1)on the XML document found on the standard input (actually theyyinfile handle: see the manual forflex(1)for information on how to change this as well as the nameyylex).
If no main action is provided, then the following is used:
int main() { exit(yylex()); }
It is advisable to use XML <![CDATA[ ... ]]> sections for the C code, to make sure that all characters are properly passed to the output file. do it for the plot β¨
Finally, note that Flexml handles empty elements <tag/> as equivalent to <tag></tag>.
π COMPILATION π
The following make(1) file fragment shows how one can compile flexml-generated programs:
# Programs.
FLEXML = flexml -v
# Generate linkable XML processor with header for application.
%.l %.h: %.dtd
$(FLEXML) $<
# Generate C source from flex scanner.
%.c: %.l
$(FLEX) -Bs -o"$@" "$<"
# Generate XML application C source to link with processor.
# Note: The dependency must be of the form "appl.c: appl.act proc.dtd".
%.c: %.act
$(FLEXML) -D -a $^
# Direct generation of stand-alone XML processor+application.
# Note: The dependency must be of the form "appl.l: appl.act proc.dtd".
%.l: %.act
$(FLEXML) -A -a $^
π BUGS π
The present version of flexml is to be considered in "early beta" state, thus bugs should be expected (and the author would like to hear about them π). Here are some known restrictions that we hope to overcome in the future:
- The character set is merely ASCII (actually
flex(1)handles 8 bit characters, but only the ASCII character set is common with the XML default UTF-8 encoding). IDtype attributes are not validated for uniqueness;IDREFandIDREFSattributes are not validated for existence.- The
ENTITYandENTITIESattribute types are not supported. NOTATIONdeclarations are not supported.- The various
xml:-attributes are treated like any other attributes; in particularxml:spacesshould be supported. - The DTD parser is presently a perl hack, so it may parse some DTDs badly; in particular the expansion of parameter entities may not conform fully to the XML specification.
- A child should be able to "return" a value for the parent (also called a synthesised attribute). Similarly, an element in Mixed contents should be able to inject text into the
pcdataof the parent.
π FILES π
/usr/share/flexml/skelβ the skeleton scanner with the generic parts of XML scanning./usr/share/doc/flexml/flexml/β License, further documentation, and examples.
okay bestie that's the whole first half β the rest of the page is still coming, so don't wander off π
π« SEE ALSO β¨
flex(1)β the og tool this whole thing is built on top of, go say hi π- Extensible Markup Language (XML) 1.0 (W3C Recommendation
REC-xml-1998-0210) β the actual spec spec, no cap, if you wanna know what XML really means π¦
π AUTHOR πΈ
Flexml was written by Kristoffer Rose, <"krisrose@debian.org">. yes that's the whole credit, one icon carrying the entire vibe, we stan π
β COPYRIGHT π
okay so legally speaking bestie, listen up, this is the paperwork part and it's giving very serious:
The program is Copyright (c) 1999 Kristoffer Rose (all rights reserved) and distributed under the GNU General Public License (GPL, also known as "copyleft", which clarifies that the author provides absolutely no warranty for flexml and ensures that flexml is and will remain available for all uses, even comercial).
no warranty means NO WARRANTY fr fr π don't come for the author if it breaks, that's the deal, that's the copyleft vibe π
π«Ά ACKNOWLEDGEMENT π
ngl this part is so sweet π₯Ή
I am grateful to NTSys (France) for supporting the development of flexml. Finally extend my severe thanks to Jef Poskanzer, Vern Paxson, and the rest of the flex maintainers and GNU developers for a great tool.
like the way they said "severe thanks"?? that's commitment to gratitude, we love to see it πβ¨
okay bestie that's the whole page π this one is perl v5.40.1, dated 2025-07-26, and it's FLEXML(1) β go compile something iconic with it, you got this, periodt π¦π
π¦ where this page comes from
- ubuntu resolute: flexml 1.9.6-6 Β· GPL-2.0-or-later
- ubuntu stonking: flexml 1.9.6-6 Β· GPL-2.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms