The '??'
operator has been supported interpreted as follows:
A ?? B
≡ (A != null) ? A : B
A
is a string, the interpretation is slightly different:
A ?? B
≡ (A != "") ? A : B
The function-call-like operator has been introduced to allow the creation of typed arrays
type[] (expr1, expr2, ..., exprN)
type
is the name of a particular type (e.g. String
, Integer
, GOMElement
)expr1
,...,exprN
are the expressions returning the corresponding array elements
GOMContext.imageMapArea
property
A new GOM (Generator Object Model) property has been introduced: GOMContext.imageMapArea
(also accessible simply as imageMapArea
).
This property is used to generate hyperlink maps for element images (e.g. diagrams).
It provides the information about a particular image area where a hyperlink should be placed.
The imageMapArea
replaces the similar old property: imageMapElement
,
which is now accessible as imageMapArea.referencedElement
.
Besides that, the imageMapArea.params
sub-property allows passing additional parameters
that can be used to generate hyperlink title (tooltip) or to find a more specific hyperlink target
(e.g. the documentation of a certain feature associated with the referenced element).
That features is now used by DiagramKit.
Several new FlexQuery functions have been added:
collectAttrValues()
, collectValuesByElements()
, collectValuesByLPath()
,
filterElementGroupsByKey()
, parseStringList()
, switch()
, SwitchCase()
To facilitate the restructuring of template applications (e.g. deriving new from the existing ones), new powerful tools for searching a template for various things have been implemented:
Search For | Search Results |
---|---|
Line number in template file *) |
The smallest template feature (e.g. template component, Location Rule, FlexQuery expression etc.), whose definition in the template file contains this line.
This type of search is helpful to quickly find the template locations reported in the generator error diagnostics
|
Use of element type |
The list of all Element Types used in the template, and for each of them, the tree of template locations, where the given Element Type is used.
|
Use of element attribute |
The list of all Element Type's attributes used in the template, and for each of them, the tree of template locations, where given attribute is used.
|
Use of function |
The list of all FlexQuery functions called in all FlexQuery expressions across the template, and for each of them, the tree of template locations, where the given function is used.
When a function is not found (e.g. it is misspelled or undefined in the given context), it will still appear in the found function list,
however, highlighted with
|
Use of property |
The list of all Generator Object Model (GOM) properties (like iterator.numItems ) set/retrieved in all FlexQuery expressions across the template,
and for each of them, the tree of template locations, where the given property is used.
When a property is not found (e.g. it is misspelled or undefined in the given context), it will still appear in the list, however, highlighted with
|
Use of stock-section *) |
The list of all stock-sections used anywhere across the template, and for each of them, the tree of template locations, where the given stock-section is called from.
|
Use of style *) |
The list of all formatting styles used in the template, and for each of them, the tree of template locations, where the given style is used.
|
Use of template parameter *) |
The list of all template parameters accessed (retrieved) in all FlexQuery expressions across the template, and for each of them,
the tree of template locations, where the given parameter is accessed.
When a parameter is not found (e.g. it is misspelled or undefined in this template), it will still appear in the found parameter list,
however, highlighted with
|
Use of template | The list of all templates (file names) called from this template, and for each of them, the tree of template locations (i.e. Call Template sections/controls), where the given called template is specified. |
Use of element map |
The list of all element maps (i.e. their identifiers) used in the template,
and for each of them, the tree of template locations, where the given element map is accessed.
|
Use of service attribute | The list of all service attributes set/retrieved in the template, and for each of them, the tree of template locations, where given service attribute is used. |
Use of user variable |
The list of all user variables set/retrieved in the template,
and for each of them, the tree of template locations, where the given user variable is accessed.
|
All disabled components/settings | All disabled components and other template locations where there are any disabled settings (e.g. hyperlink/target definitions, style overrides, location rules etc.) |
All hypertext links and targets *) | All hypertext link/target definitions found in the template. |
All specified expressions *) | All template locations where there are specified FlexQuery expressions. |
All specified formatting properties | All formatting properties of template components or formatting styles found in the template that have specified values. |
All string constants | The list of all string constants specified in all FlexQuery expressions across in this template, and for each of them, the tree of template locations where that string is used. |
All text labels and separators |
The list of all text labels and separators specified across in this template, and for each of them,
the tree of template locations where that label/separator is used.
The text labels/separators are just another type of string constants, however, specified not in FlexQuery expression
but rather in properties of template components (e.g. Text Controls).
|
*) These search criteria were supported before, but now they have been reimplemented and enhanced to find all lost (misspelled/undefined) things.
All found template locations are shown in the form of a tree (including all parent components), from where you can easily jump to the actual template components in Template Designer.
When several matching locations are found within the same FlexQuery expression, the counter of those instances will be shown by the node representing that expression in the template location tree. Further, all found instances can be viewed in details via «View Expression...» item in the local menu invoked from that node.
The search dialog is invoked from the Template Designer main menu > Edit > Find... item. Besides that, the same search can be run from the local menu for a selected template parameter, formatting style or stock-section at their definitions.
It was also supported that when the search dialog is closed, all its current state (including the selected search criteria, the selected found item, the selected node in the template location tree) is saved and restored back into approximately the same state (or the closest one), when the search dialog is invoked again. That allows you quickly to visit all found items / template locations one after another so as to edit them (or do something else).
Because of the absence of demand, the integrations with Altova XMLSpy® / Oxygen XML Editor, which allowed using these third-party software as external diagramming engines for XSDDoc/WSDLDoc, has been discontinued and deleted from FlexDoc/XML.
For those, who used these products earlier, we recommend to switch to DiagramKit.
We have migrated the implementation of the entire FlexDoc/XML into modular Java. It means the following:
flexdoc-xml-diagramkit.jar
flexdoc-xml-xmlspy.jar
flexdoc-xml-oxygenxml.jar
Before Java 11, JavaFX was a part of the standard Java SE. So, no problem existed to run FlexDoc/XML+DiagramKit immediately on any Java installation.
But since Java 11, Oracle has moved JavaFX into a separate project found on openjfx.io. Now, those who need JavaFX should download JavaFX SDK separately from there, install it and specify all JavaFX dependencies in their Java application according to that installation. That, of course, may be too complicated for ordinary users, and breaks down the whole idea of using some generic Java pre-installed on user's computer (independently on FlexDoc/XML).
To work around that problem, now, we offer a custom JRE (called «FlexDoc JRE»), which is a set of {OpenJDK+JavaFX} images prepared to run FlexDoc/XML+DiagramKit immediately on Windows, macOS and Linux.
Just download it from https://www.flexdoc.xyz/downloads/ and don't bother with anything else!
The support of OASIS XML Catalogs
has been migrated from Apache Xerces API
to the the standard Java API: javax.xml.catalog
.
So, no additional {flexdoc-xml}/lib/resolver.jar
is needed any longer.
The algorithm of wrapping of long non-breaking strings in tables has been improved.
The only way to deal with that situation was to break such strings artificially by inserting new-lines. However, to do it properly and reliably, the whole table must be laid out beforehand (that is somehow estimated, how MS Word would do it).
Fortunately, since circa 2010, MS Word does provide a special 'Non-Width Optional Break' character, using which you can insert a hint, where the string may be broken, when it needs to be wrapped. This, however, still doesn't solve the problem completely, because the result table must look balanced, so that some of its columns do not degenerate into nonsensible width.
We have already implemented a bunch of RTF options to deal with that problem (see Tables | Break long nonbreaking strings).
What we have added now is that when 'Use optional breaks' option is specified and a non-breaking strings exceeds the 'Maximal unbroken length', all non-letter-or-digit characters that follow that length are appended with the 'Non-Width Optional Break'. Then, the wrapping of such a string will look smarter.
For the purpose of better visibility of our software in Internet and promotion, we have made some renaming and relocation with the following effects:
You can equally install any your old licenses for DocFlex/XML software with the new FlexDoc/XML the same way as before. You should neither rename anything in your license files nor change the file names!
com.docflex.*
moved to xyz.flexdoc.*
urn:flexdoc-xyz:xml:defaultcatalog
A bug has been found in the interpretation of the multi-row spanning table cells defined in templates. In some rare situations when running WSDLDoc, that bug caused NullPointerException. Now, it is fixed.
DocFlex/XML uses Apache Xerces2 Java Parser
to read all XML files (as well as XSD files in some special cases).
It is included in DocFlex/XML archieve and found in 'lib'
directory (see Package Contents).
Several bugs have been fixed in the Template Designer (caused by the migration to Java 8 generic types).
Now, DocFlex/XML has its own (independent on any third-party software) diagramming engine called «DiagramKit». It creates beautiful XSD component diagrams, which can be generated/inserted simultaneously along with the documentation generated by both XSDDoc and WSDLDoc (with the support of all possible hyperlinks). «DiagramKit» is included in DocFlex/XML software and will work by default.
Special efforts have been made to ensure that DocFlex/XML works properly on macOS and can be immediately used there, namely:
.command
files have been included to
A new template section was introduced, whose job is only to execute the specified FlexQuery expression.
There is a demand for such sections within init.tpl
template (in both XSDDoc and WSDLDoc template sets).
That template generates no output, but loads all WSDL/XSD files and creates a number of element maps used across
the entire template set. That's done by executing lots of FlexQuery expressions specified in various template sections.
Previously, as a surrogate for Query Sections the Folder Section were used with the specified Init Expression.
That looked confusing and burdened processing.
A few minor bugs have been fixed.
file:/C:/Service/Service0.xsd
file:///C:/Service/Service0.xsd
file://
The possibility of designing tables in templates has been considerably extended.
Now, you can define dynamic tables of any complexity, with some cells spanning both several columns and several rows. (Before this version, only multi-column spanning cells were possible.)
That is supported both:
At that (as always), the tables defined in old templates will remain the same and work perfectly as well, with no need to change anything in them.
Four more types of template formatting styles have been supported:
Besides simplifying programming of templates, template styles can be rendered into similar structures of particular output formats.
For instance, in HTML output the template styles can be translated into
named CSS rules, which allow you to substitute particular formatting properties
using purely HTML/CSS means (e.g. custom CSS file).
See also: templates/WSDLDoc/CHANGES.html
| Version 1.1.0 | Styling HTML documentation with custom CSS
Before this version only two style types were supported:
The formatting of lists has been enriched with two more properties:
Property | Description |
---|---|
List | Bullet | Image File | Specify the bullet image file. This property allows you to replace the standard list bullet with a custom image. |
List | Bullet | Image Output Directory Expression | Specify the FlexQuery expression that generates the pathname of the output folder where the bullet image file is to be stored (typically, it is with all other icons). |
This property helped us to optimize some fragments of WSDL documentation so as to make them both more compact and clearer.
A new text formatting property has been supported: character spacing (e.g. see: Text Control | Properties Dialog | Formatting | Text | Spacing | Character spacing).
It allows you to specify spacing between characters in length units. The main benefit of this property is a possibility to specify exact spacing between short pieces of text (which, for instance, may serve as items of a horizontal menu).
A new template component has been added, which represents a page-break (e.g. see: Area Section | Local Menu | New Area Row | Page Break).
Previously, page-breaks could be specified only as formatting properties of template Sections, which made them difficult to control. A separate component gives a lot more flexibility (through the enabling condition) as well as visualizes page-breaks in Template Designer.
The early "Delimiter Control" has been renamed into "Separator Control" for better clarity.
Of course, any existing templates won't be spoiled by that!
Now, you can search templates for a lot of various things:
Search For | Search Results |
---|---|
Line number in template file | A template component, whose definition in the template file both contains this line and the smallest one. The purpose of this type of search is finding the template locations mentioned in the generator error diagnostics. |
Parameter name | All template locations where there is access to a template parameter with that name (including the parameter definition). |
Stock-section name | All template locations where a stock-section with that name is called (including its definition). |
Style name | All template locations where a formatting style with that name is used (including its definition). |
Unknown (lost) parameters | All template locations where there is access to template parameters, whose definitions are absent. |
Unknown (lost) stock-sections | All template locations where there calls to stock-sections, whose definitions are absent. |
All hypertext links and targets | All template locations where hypertext links/targets are defined. |
All specified expressions | All template locations where there are specified FlexQuery expressions. |
The found template locations are shown in the form of tree (including all parent components), from where you can easily jump to the actual template components in Template Designer.
The search dialog is invoked from the Template Designer main menu > Edit > Find... item. Besides that, the same search can be run from the local menu for a selected template parameter, formatting style or stock-section at their definitions.
Panel Control is a Control with a template area inside. That means it may contain other components (Area Rows and Controls) that define some complex content.
When a Panel Control defines a table cell, it should also somehow visualize the cell alignments. Previously, only horizontal alignment was shown on the level of Control Groups (which are the Area Rows containing Controls). Now, in addition to it, all Area Rows defined within the Panel Control are together aligned vertically as well. That depicts much better how the result table will look in the generated output.
It was possible once again to find and optimize some bottlenecks in the template interpretation. Now, all output generators work 20-30% faster!
That is, if the generation of some enormous XML schema documentation with the previous DocFlex/XML version took 30 minutes, now that may last a little more than 20 minutes. (Note: the generation of diagrams is not included in that calculation.)
The error diagnostics issued by the template interpreter has been completely reworked. Now, the full template location trace is reported with the corresponding line numbers in template files (similar to Java Stack Trace). Additionally, for some components, their context element is reported that shows which XML element (along with its XML file) was being processed by the given template component at the moment of the error. For example:
-------------------------------------------------------------------------------- ERROR DETAIL -------------------------------------------------------------------------------- Generator Exception: Stock-section recursion depth overflow -------------------------------------------------------------------------------- at Stock-Section 'complexType' / Folder Section for 'xs:%complexType' (complexContentModel.tpl:492) with context element: <xs:complexType name="AuthenticationType"> (C:\XSD\configuration.xsd) at Call Stock-Section 'complexType' (complexContentModel.tpl:449) at Element Iterator by 'xs:extension (xs:%extensionType)' (complexContentModel.tpl:434) at Stock-Section 'complexContent' / Folder Section for 'xs:complexContent' (complexContentModel.tpl:427) with context element: <xs:complexContent> (C:\XSD\configuration.xsd) at Call Stock-Section 'complexContent' (complexContentModel.tpl:502)
Although templates are not supposed to be edited manually, you can use the template line numbers in Template Designer to find the corresponding template locations (see template search tools).
The WSDLDoc template set (the implementation of a WSDL/XSD Documentation Generator) has been greatly advanced. Key new features:
See more details at: templates/WSDLDoc/CHANGES.html
| Version 1.1.0
The lite edition of DocFlex/XML (called «DocFlex/XML RE») has been eliminated.
The reason is that by the time the lite edition has evolved into the same as the full one, except it included no Template Designer. Since currently different features of DocFlex/XML software are licensed separately anyway, no matter where they reside, the lite edition is redundant – just draws resources to maintain it.
Now, only the full edition of DocFlex/XML (called simply «DocFlex/XML») is available, which includes all features/functionality developed in this product line (however, grouped in different logical products with separate licensing).If you have been using DocFlex/XML RE, now simply install and use the full edition. Equally, install your licenses there. Everything else is the same.
Now, DocFlex/XML includes one more big template applications called «WSDLDoc», which implements a powerful WSDL/XSD documentation generator. Made of 100 templates and controlled by 700+ parameters, it is the most complex end-user application of the whole DocFlex Technology to date!
The editor of template parameter definitions (found in the Template Property Dialog | Parameter tab) has been completely reworked.
Previously, that was just the plain list with each line representing a parameter. As the number of parameters in some templates has grown to enormous quantity, that list eventually became practically unnavigable.
Now, the parameter definitions are represented in the form of tree with collapsible nodes (the same as in Parameter Inspector). Thereby, the usability of the parameter definition editor has been restored.
Some XML files may be described by not a single but several XML schemas at once. For instance, an XML file as a whole (starting from the root element) is described by one XML schema, but some internal parts of it – by another XML schema (even completely unrelated to the first one).
That's actually the case of WSDL files.
A WSDL 1.1 file as a whole is described by the schema: http://schemas.xmlsoap.org/wsdl/
.
But the <wsdl:definitons>/<wsdl:types>
element typically contains
one or many XML schemas embedded in that WSDL file, which are described by a different schema:
http://www.w3.org/2001/XMLSchema.xsd
That capability is critical for WSDLDoc template set.
When you have to process at once (i.e. generate a single documentation for) so many input XML files that it is impractical to list all of them as generator arguments, now, you can use Ant-style file pathname patterns to pick all input XML files you need.
For more information, please see: DocFlex/XML | Documentation | Running Generator | ... | Using file pathname patterns.
When a text (e.g. XML schema annotations) preformatted with HTML tags contains repeating whitespace (i.e. space and newline characters), those repeatings won't appear in the generated RTF output (the same it would be in case of HTML browsers).
That was not provided before this version.
A possibility has been supported to include a static Word document in the RTF document generated by DocFlex. That is done through a Data Control with the data source specified as "Document Field". A new "Include Text" field has been implemented. The included Word document file must be specified with the "Expression for Filename or URL", the parameter of that field.
See: integrations/OxygenXML/README.html
| Change Log | Version 1.5
Template Call is a template component that allows you to call one template from another. Here, the called template (or subtemplate) serves as a procedure. It may generate either a separate file or a piece of the file generated by the calling template. A Template Call has a lot of settings (among them, of course, passing template parameters).
Now, one more group of settings has been added – the list of style overrides.
Each template may define formatting styles. These are the named groups of formatting properties, which can be assigned to a template component at once just by specifying the style name. The formatting styles are template local things. That is, they are not imported from somewhere outside. But when a template is called from another template, the styles defined in the calling template will override the equally named styles defined in the called template. When multiple templates are called one from another, that will work in a chain. So, the styles defined in the main template will override any equally named styles defined elsewhere. As a whole, formatting styles behave as additional template parameters passed implicitly by their names.
Now, it is possible also to specify explicitly for a given Template Call how the style overriding occurs. For each style found in the called template, a style override can be defined that tells exactly which style from the calling template will override it (regardless of the style name). That adds a lot more flexibility!Style overrides are specified in the Template Call property dialog on the "Call Settings | Style Overrides" tab.
The HTML generator has been almost entirely redeveloped to achieve the following goals:
Now, the HTML output can be generated in one of the markups:
The markup is selected with the option: Output | Markup
For those who wanted to customize the generated HTML documentation with their own CSS rules, it is possible now!
In case of HTML output, the CSS style sheet has been used before, but the CSS rules placed in it were effectively the sets of inline CSS properties generated by particular template components and collected together in a single style sheet to eliminate their repeating. The class selectors assigned to such CSS rules were completely unpredictable and could not be used to substitute the generated CSS rules with the custom ones. Such automatic CSS rules are generated now too and called anonymous CSS rules.
Starting from this version, a new type of CSS rules has been supported – named CSS rules. Those are generated from the formatting styles defined in templates. When such a style is assigned to a template component, each piece of HTML output (i.e. HTML element) produced by that component can be assigned with the CSS rules generated by that style. The class selector assigned to a named CSS rule is specified in the corresponding template style. So, the relation between a particular CSS class selector and the pieces of output where it is applied is predetermined. This makes possible to substitute the CSS rules (i.e. their properties) generated for those class selectors automatically, with the custom CSS rules provided by the user.
The difficulty of implementing of named CSS rules comes from the fact that several template styles can contribute to the result formatting of a particular template component. The styles can be either assigned directly to the component or inherited from its parents. Besides that, some formatting properties can be specified on the component directly without any styles at all. When that everything is rendered with a single anonymous CSS rule, only effective properties (left after all overriding) will get there. But when named CSS rules are used, they must replicate in CSS the same property overriding that occurs on the level of template styles. That wasn't simple to achieve!
For a lot more details please see: DocFlex Technology | Documentation | Usage of CSS in generated HTML.
See also: DocFlex Technology | Documentation | Usage of CSS in generated HTML
This option was actually present before, however not in this group.
Generation of named rules is essential for applying custom CSS rules
This setting is essential for applying custom CSS rules
The possible are relative, pixel and point units.
This setting may be particularly important in case of XHTML output.
An integration of DocFlex/XML with Oxygen XML Editor
has been implemented.
For all details, please see integrations/OxygenXML/README.html
and
Documentation | Integrations | Oxygen XML.
For Image Control, it is possible now to specify paddings around the image. See: Image Control | Properties dialog | Formatting | Image tab.
The image paddings are supported in both HTML and RTF output formats. They may be particularly useful when inserting various icons in the documentation.
A few minor bugs have been fixed.
Among them, it turned out that sortVector()
FlexQuery function was sorting strings
always ignoring case. In XSDDoc, in rare cases, this caused incorrect unifying local elements by type.
Now all output documents (in HTML and RTF formats) generated under the general Trial License will be distorted by replacing some letters with bullet characters (as well as contain special messages).
The Java-style typecast operator has been supported:
(type) obj
type
may be any primitive type (like String
or Number
)
or GOM-type ("GOM" stands for Generator Object Model).
It allows you to quickly access properties of various GOM objects, provided via untyped references (mostly returned by various functions). Now, you can write something like this:
((GOMElement) getParam("name")).id
toString()
or toElement()
)
were available for such operations.
Casting to array types is also supported. You can write:
(type[]) obj
obj
is an array
of a more generic type, however, containing only elements of the required type. For example:
objects = Array (1, 2, 3); // create an Object[] array with only integer elements ints = (int[]) objects; // convert it to an array of integers ints[0] * ints[1] * ints[2] // access array elements as integers
A new property has been added to Image Control: "Expression for Image File Name". It generates a name of the output image file.
This feature is most interesting in the case of element images, which are certain graphical depictions (e.g. some diagrams) of the entities represented by the DSM elements.
Previously, the names of the element image files were produced from certain DSM element properties (their internal names and types), which was hardcorded in the generator.
It may sound odd. What images and hyperlinks can exist in plain-text files?
Yet, the plain-text output may be just a base layer for other file formats, for instance DITA, which is an XML-based markup. There, both images and hyperlinks do exist and are required.
The following new functionality will allow you to use plain-text output capability of DocFlex/XML to generate some full-blown complex formats even when they are not supported by DocFlex/XML directly.
Images
In plain-text mode, an Image Control will produce the same image file (according to its setting). However, in addition, it also emits into the main output the image file's relative pathname. That pathname is calculated against the main file's location and the name-separator is UNIX style ("/"). In a template, you can surround the Image Control with other Text Controls generating some markup, so everything would produce both the image file and the image tag for it in the main output.
Hyperlinks
Now, you can generate cross-hyperlinks in plain-text files too. This equally includes the hyperlinks from images (the imagemaps).
What a hyperlink actually is depends on the final format you generate using the plain-text output. DocFlex/XML just provides the necessary functionality to find the things you want to link from and to. This is implemented in the form of new FlexQuery functions and GOM types/properties ("GOM" stands for Generator Object Model):
Function / Type / Property | Description |
---|---|
findHyperTarget() |
Finds a hypertarget matching the specified set of keys that may exist anywhere
in the whole generated documentation. Returns a GOMHyperTarget object
describing the target.
|
GOMHyperTarget |
Provides information about a hyperlink target. This includes the output file containing the target and the target name. |
getElementImageMapAreas() |
Returns all hypertext imagemap areas of the element image associated with the specified element.
The function returns an array of GOMImageMapArea objects.
|
GOMImageMapArea |
Represents a single area in the hypertext imagemap of an element image.
This includes the area bounds (rectangle) and the referenced GOMElement .
|
GOMElement.hasImage |
Indicates whether the element has a certain image representation (called element image). |
More information about these functions and types you can find in the Template Designer | Help | Assistant:
Template calls are the template components that invoke processing of other templates from the given one (typically to insert their output into the currently generated document).
Processing of a template call is rather time-consuming. The fewer of them are in a template the better they can be optimized. Moreover, templates cannot be called directly from FlexQuery expressions.
The solution is to use stock-sections as light-weight proxies of template calls (stock-sections can be called also from FlexQuery expressions). That is, a template call is defined only once within a stock-section, and then that stock-section is called from anywhere, instead of the template.
Previously, that was possible only by defining a Folder stock-section and the Template Call Section within it.
Now, a Template Call Section itself can be specified as stock-section (which, of course, reduces all the processing).
DSM stands for Data Source Model. DSM Type is a description of particular class of possible data sources processed by a given template.
In DocFlex/XML, DSM Type is called XML Type, since all data sources are typically XML files.
Now, a special DSM Type has been supported: Any Data Source.
A template based on it can be called to process any data source (or even no data source at all).
It can be called also from any other templates.
This, however, comes to a price. Such a template can do little more but process only template parameters
and #CUSTOM
elements.
Anyway, it might be useful. For instance, you can create a template that inserts in the output some complex richly formatted messages, which are the same for all template applications. It is also possible to pass quite complex data via template parameters (and even iterate by them).
The template file format has been made more friendly to view/edit template files manually (without Template Designer):
'\n'
escapes).
'\uxxxx'
).
'DSM_TYPE_ID'
property can be change manually now.
The 'DSM_TYPE_ID'
property specifies the XML Type, on which the template is based.
XML Type provides the structure and data type information about possible XML files processed
by the template.
Expression Assistant provides a dynamic help system when writing FlexQuery-expression (those used to calculate various dynamic properties of template components and for other things).
As the number of FlexQuery-functions constantly increases (many actually overload the same functionality with different parameter signatures), the function tree in the Expression Assistant has been reorganized as follows:
The primary focus of the generated RTF was always MS Word. However, following some user complaints, we uncovered and fixed a lot of problems of compatibility with other RTF readers. For instance, under WordPad, certain features of the old RTF output might be distorted, or the whole doc might get invisible starting from some point.
RTF is poorly documented format ridden with various legacy contradictions. So, it is not very simple to get all known RTF reader work correctly together, particularly, when you have a rather complex RTF.
Now we've fixed a lot of such issues. So, the generated RTF seems to work OK with all RTF reader we tried:
A bug has been fixed that in some cases caused distortion of text of formatting in page headers/footers.
See: integrations/XMLSpy/README.html
| Change Log | Version 1.5
The full edition of DocFlex/XML software, which was formerly called "DocFlex/XML SDK", is renamed back to "DocFlex/XML (Full Edition)" to reflect the fact that a "DocFlex/XML SDK" license does not cover the whole DocFlex/XML software.
The "Label Control" has been renamed into "Text Control" and more functionality added.
The purpose of Text Control is to specify some static text in templates. Now, unlike the old Label Control, it shows the full multi-line text directly in the designer pane (with the support of scrolling). This may be particular helpful, when you want to specify in templates some multi-line descriptions.
A new property has been introduced for Element Iterators: "Expression for Grouping Key" (found on the "Processing | Sorting/Grouping | Grouping" tab of the Element Iterator properties dialog in the Template Designer). It allows you to break the iterated elements into groups so as to iterate, first, by the groups and, then, by the elements within each group.
It works as follows.
After the initial elements have been collected, filtered and sorted, the result sequence of elements is broken into groups according to the grouping keys generated for each element by the FlexQuery specified in the "Expression for Grouping Key" of the Element Iterator.
Each continuous subsequence of elements with equal grouping keys produces a group. As a result, the sequence of elements prepared for iterations is converted into a sequence of element groups. The ordering of elements in each group remains the same as in the initial sequence.
Since groups are not elements, the Element Iterator cannot iterate by them directly.
So, it will iterate by the first elements taken from each group.
However, at that, on each iteration step, the Generator Object Model (GOM) property
iterator.groupElements
, which is accessible in FlexQuery expressions,
is updated so as to provide the enumeration of all elements
in the given group.
This allows you to specify a nested Element Iterator that will iterate by the elements
in the group received from the iterator.groupElements
property.
Although, dynamic HTML is not currently in the focus of DocFlex templates, the following setting has been supported: Template | Properties | Output File | HTML Head Expression.
It specifies an expression that may produce a string, which will be included in the header (between <head>...</head> tags) of an HTML file generated by the given template. In particular, this allows you to embed in the generated HTML file any custom JavaScript code (enclosed in <script>...</script> tags).
For instance, this may be used to reload the 'detail'
frame
(of a frameset defined in index.html
) with another HTML document passed
to index.html
via a URL parameter (specified after '?' in the initial URL).
That was actually supported in XSDDoc templates;
see:
templates/XSDDoc/CHANGES.html
|
Version 2.5.0 | Opening of frameset on required page
Hyperlinks are generated according to special link/target definitions specified in template components (see component's Properties Dialog | Hypertext tab). Now, hyperlink definitions themselves look more like components. The following settings/features have been added:
Some hyperlink definitions may be so complicated that they are better to be explained.
The same as in template components, it allows switching context element used for calculations of other hyperlink's settings.
Specify one or several element types, which the context element must match. This is a kind of filter. If the context element does not match any of the specified types, the whole hyperlink definition will be skipped.
A hyperlink is created when the vector of keys generated by the Link Key Expressions matches a similar vector of keys associated with a certain target (generated by a different component).
Now, in addition to single vector of keys, it is possible to define matrix of alternative keys. The matrix columns become alternative key vectors. If one vector cannot be matched, another is tried.
This allows unifying in a single hyperlink definition what were previously several ones, which simplifies programming and improves performance of the template.
Image Control has been extended with a new property: "Expression for Image File Output Directory", which allows programming where the images produced by a given Image Control will be stored. In particular, this makes possible to save all standard documentation icons in a single directory (and, therefore, to prevent duplicating them):
{doc-root}/resources
This is supported now in XSDDoc templates;
see:
templates/XSDDoc/CHANGES.html
|
Version 2.5.0 | Single directory for all documentation icons
FlexQuery expressions are small program blocks (called queries) with a Java-like syntax that are used in templates to calculate dynamic properties of template components and for other needs.
Now, the FlexQuery language is extended with the return statement:
return <result_expr>
result_expr
specified in the return statement.
The type of the returned result is checked to comply with the data type necessary for the given query. This is done yet during the parsing of the query (e.g. in Template Designer).
A FlexQuery expression may also contain subqueries, which are nested code blocks executed not directly, but rather passed as parameters to functions. A function may call such a subquery repeatedly to calculate certain things (e.g. to check a filter condition for the elements processed by the function).
A subquery may also contain return statements, which will affect only the execution of that subquery.
The result_expr
specified in such a return statement will be also checked, however,
now only to comply with the data type necessary for the given subquery.
Embedded HTML is the HTML markup (tags) inserted by the user directly in various descriptions, annotations etc. (stored as plain text in XML files) in order to format them. To have that formatting show up in the generated documentation, in general, the embedded HTML markup needs to be processed (rendered) specifically, which depends on the output format. This is controlled by the "Render embedded HTML" option of the given output format.
Sometimes it is needed to remove all block-level HTML tags but leave any other tags, so that the result text would be displayed formatted but without any structure, as a single line. That, we call flattening.
It is supported now!
A new formatting property has been introduced for all template components: "Embedded HTML | Flatten" (found on the "Formatting | Text Flow" tab of the component properties dialog in the Template Designer). If it is selected, any embedded HTML markup found in the text output produced by the component will be flattened (given that the embedded HTML is processed both as a whole and for that component in particular). This will also affect all nested components (including called stock-sections), unless rendering of embedded HTML is specifically disabled in some of them.
Before this version, all descriptions of templates and their parameters could be stored only directly within the templates themselves. Now, they can be held also in separate text files located near the main templates. (The description text may also include HTML markup.)
This makes possible:
That functionality is achieved by introducing of a new macro:
${include <url>}
The url
specified in the macro points to the file to be included.
The macro is expanded with the content of that file (after the expansion of any include
macros found in that file).
The file URL may be both absolute and relative one. If the macro is found within a description stored in a template, the relative URL is interpreted against the location of that template. If the macro is found within a text file, the URL is interpreted against the location of that file.
This everything has been applied in XSDDoc
templates; see:
templates/XSDDoc/CHANGES.html
|
Version 2.5.0 | Separation of parameter descriptions from templates
Now, in the Parameter Inspector, those parameters that are irrelevant to the current settings (specified in other parameters) can be shown disabled. This will help navigating the parameter tree.
That is achieved by introducing new properties in the template parameter definition: "Enabling Condition" and "Group | Enabling Condition". They specify the boolean FlexQuery expressions (queries) that are evaluated each time any of the template parameters is changed:
Procedure templates are a special kind of templates that generate no output. Rather, they have been used internally in big template applications to employ the data querying and processing capabilities of template components (such as Element Iterator) for some auxiliary tasks (e.g. creating of element maps).
Now, the role of procedure templates has been extended, so they can be used also to generate multi-file documentation with no particular root. The following functionality has been supported:
A default XML catalog has been introduced. Its purpose is to point to the local copies of some standard XML schemas found in Internet (like http://www.w3.org/2001/XMLSchema.xsd), which are critical for XSDDoc templates.
Previously, those schemas were held along with the XSDDoc templates in the directory:
{docflex-xml}/templates/XSDDoc/xmltype/
{docflex-xml}/lib/resources/
The default XML catalog, which is located in the same directory in the file:
{docflex-xml}/lib/resources/catalog.xml
Now, you can document your entire XML schema project even when it is packed in a jar-file!
For example, suppose you have a jar-file 'C:\project\some.jar'
,
in which there is 'xsd'
directory containing an XML schemas 'some.xsd'
.
Then, the URL to be passed to the generator to document that XML schema should look as follows:
jar:file:/C:/project/some.jar!/xsd/some.xsd
All internal CSS declarations, which were previously defined and used only locally in every generated HTML document,
now can be held in a single 'stylesheet.css'
file stored in the documentation root.
Only links to this file will be included in the generated HTML documents.
Although such CSS declarations look typlically rather gibberish, they tend to repeat across HTML files. So, moving them to a single CSS file may substantially reduce the overall size of the generated HTML documentation.
That possibility is controlled by a new "Output | Generate style sheet file" option.
What's more, using the nested "CSS pattern file" option, you can frame the generated CSS declarations into your own CSS file. That will allow you to include in the result CSS file your custom styles, which you can use to format the HTML markup embedded in your descriptions/annotations.
When you frequently upload the generated docs into some repository, which stores only changes of files against their previous versions and your docs actually do not change, this will relieve the repository from unnecessary updates.
Thanks to all recent innovations, including storage of all internal CSS declarations in a single CSS file (see Generation of CSS file) and many others, the HTML generator works now on average 5% faster and generate output 15% smaller against DocFlex/XML 1.8.0.
Before this version, all formatting styles defined across a template set, which are not overridden by other equally named styles from parent (calling) templates, would produce the same number of separate styles in the RTF.
Now, this is changed:
That optimization prevents the contamination of the generated RTF with many unused styles (which have been defined in templates but never used) and duplicated styles (which are defined in several subtemplates, but never in the main one).
The automatic wrapping of very long nonbreaking strings within table cells has been reworked once again.
The problem is that MS Word cannot wrap such strings by itself, which causes the table to stretch beyond the visible page.
The previous algorithm worked well when such strings appeared only in one table column. But when they happened to be in several columns, the algorithm failed and the table was laid out by Word again beyond the page width.To deal with that problem, the following things have been implemented:
The src
attribute now can specify not only a formal URL but also a local file pathname
(e.g. c:\element.gif
). Such an image will be shown in RTF.
Also, when the image file specified in src
attribute cannot be found and
the "Images | Show failed image path" RTF option selected,
the failed image's pathname (or URL) will be shown in the generated RTF (along with a placeholder).
Previously, all <img> tags with failed images were just ignored.
That has been completely reworked.
Previously, when "Text | Render line breaks" RTF option was selected and some embedded HTML happened to contain table tags (<table>,<tr>,<td>) intermitting with newlines, the rendering of such a markup in RTF could produce tables with extra cells. Now, this is fixed!
Before this version, when some HTML formatting was specified within a table cell, like:
<table><tr><td><font color="red">blah-blah-blah</font></td></tr></table>
'blah-blah-blah'
wouldn't be red). Now, this is fixed!
Specification of the size and scaling of EMF images in RTF has been completely reworked.
As it was implemented previously, some EMF images inserted by DocFlex in RTF were scaled incorrectly by MS Word, which resulted in displaying of too small or too large images (particularly, when the goal was just to make an image/diagram fit best in the available page size). Now, it is fixed (see below)!
EMF is a vector graphic format, which is especially useful for various diagrams. It is widely generated by many software systems (thanks to its direct support by MS Windows itself, via its APIs).
width pt * 5/3
5/3
factor is used by MS Word 2000 to display PNG and GIF images.
Their pixel size visible in MS Word is calculated as follows:
image size pt = image size pix, from image file / 96 screen dpi * 72 points per inch
image size pix, in MS Word 2000 = image size pt * 5/3
\picscalex
& \picscaley
commands specified in RTF.
So, to be stored in RTF, the original EMF image size in pixels must be converted first
into some non-pixel units – e.g. points, which can be converted further to mm according to standard
formula – that will be interpreted correctly by MS Word.
(In fact, EMF file does include the image size specified in 0.01 mm, but it cannot be used here
because MS Word 2000 completely ignores it.)
From the investigation above, we've got an idea. The point size of an EMF image (to be used
for RTF) should be calculated like this:
image size pix, from EMF file * 3/5
This option lets you define what a long nonbreaking string actually is (thereby preventing breaking of some resonably long words and names).
For all details, see the description of this option in: Generator GUI | Output format | RTF | Options | "RTF Option" dialog
The DocFlex/XML core (namely, XML DSM [Data Source Model] driver) has been extended with an abstract functionality that allows dynamic association of some XML elements with certain graphic representations of them called element images (which are typically some diagrams). Such images may be also supplied with hypertext imagemaps, which enable generation of hyperlinks from the specific image regions to the corresponding locations in the documentation.
The element images (and imagemaps to them) are not generated by the XML DSM driver itself. Rather the driver exposes a special Element Image Provider interface, which may be implemented by another extension (or integration) specific to a particular template application field. Such an implementation should "understand" the semantics of the underlying XML data source and generate diagrams/images (along with the imagemaps) that somehow depict particular XML elements.
When supported, element images are accessible in templates via Image Controls, which makes possible to program how those images are inserted in the generated output, formatted and hyperlinked to other documentation parts.
The new Element Image functionality was immediately used to develop the XMLSpy Integration (see below).
A new property has been introduced for template sections: "Output Notification Expression" (found on the "Component | Options" tab of the section property dialog in the Template Designer).
When that expression is specified, it will be executed each time the section has produced a non-empty output (on the finishing of the section processing).
This makes possible, for instance, to program such things like tracking whether particular output sections have been generated early and, depending on it, to add some kind of separator (e.g. horizontal rule) before the output that follows them.
A new functionality has been supported that makes possible to dynamically attach any data to particular DSM elements using special service attributes.
Service attributes serve the same role as normal element attributes. They allow you to attach specific data to particular DSM elements and access those data by names. However, unlike normal DSM attributes, service attributes are not provided by the DSM driver and not connected to the external data source. Rather, they are maintained by the generator itself in the form of a special hash-map.
That hash-map is actually very simple. Each service attribute is represented by a two-part key: { attrName; element.id }, where 'attrName' is the attribute name; 'element.id' is the unique identifier of the DSM element, to which the attribute is attached. Such a key is mapped to the attribute value.
The main purpose of service attributes is to use them as a data cache. That is to store some frequently needed information about particular elements, which although can be found in the DSM, practically is difficult to collect.To work with service attributes, the following FlexQuery functions have been added:
Function | Description |
---|---|
setServiceAttr() |
Assigns a service attribute with the specified name and value to the specified element. |
getServiceAttr() |
Returns the value of a service attribute with the specified name attached to the specified element. |
hasServiceAttr() |
Tests if there is a service attribute with the specified name attached to the specified element. |
removeServiceAttr() |
Deletes a service attribute with the specified name attached to the specified element. |
The full descriptions of those functions can be found in the Template Designer: Help | Assistant | Functions by Category | Elements / Attributes | Attribute Access.
This new functionality was immediately used in
XSDDoc templates.
See:
templates/XSDDoc/CHANGES.html
|
Version 2.2.0 | Naming of redefined components
The HTML output generator was optimized to work about 5% faster and now produces more compact output (1-5% smaller size).
Besides this, the following HTML options have been added:
"Use fixed font sizes"
This option is not exactly new. It replaces the previous "Use relative font sizes" option, which had the opposite meaning.
Several new RTF output options have been added to control generation of hyperlinks and bookmarks:
"Hypertext | Generate hyperlinks"
Note: To have cross-reference hyperlinks (those pointing within the same document) be generated, the "Generate bookmarks" option must also be selected. Without it, only external (URL) hyperlinks will be possible.
Bookmarks are needed to generated both cross-reference hyperlinks and page number references.
This option may be useful when you need to merge several RTF files produced with DocFlex into a single document. In that case, you should generate those files with different bookmark prefixes. This will ensure that the bookmarks from different RTFs never overlap and all hyperlinks and page number references in the result document are correct.
"Images | Allow image rotation"
For the case when the generator is run from Java command line (e.g. using generator.bat
) and with GUI,
the generator dialog
has been re-implemented using JFrame so that it will be visible on the Windows taskbar
as a Swing application.
First sentences of description texts are used in various summary tables.
In a plain text, the first sentence is defined by the position of the dot ('.'
)
that ends the sentence.
When a text is formatted with HTML, extracting its first sentence becomes trickier.
In that case, besides the dot, a sentence may be terminated with a block-level tag.
In the early implementation,
all such tags were taken into account. Now, all heading tags (like <h1>
) are ignored.
So, when a text has a heading, it will be just added before the first sentence extracted from the actual text,
but not replace it. This will make those short descriptions placed in summary table be more informative.
An integration of DocFlex/XML with Altova XMLSpy® has been implemented.
For all details, please see integrations/XMLSpy/README.html
and
Documentation | Integrations | XMLSpy.
To make things clearer and more convenient to the users, the following changes has been made in the DocFlex/XML product range:
Nothing has changed, however, either in the provided content/functionality or licensing of this edition. Any Commercial or Academic licenses issued previously for "DocFlex/XML" can be installed and will equally work with DocFlex/XML SDK.
That edition (the interpretor/generator itself) has been made freeware to provide the free runtime environment for execution of DocFlex/XML templates. The output generators will work without limitations (on the features of the generated output). No, special licensing is needed for this any longer.
However, the actual limitations on what you can generate may come from the template applications, which may require special licensing by their own (or need to be created/modified under a Commercial License for DocFlex/XML SDK). See also Licensing of Templates for more details.
As it was before, DocFlex/XML RE is bundled with all currently available template applications developed by us (some of which require separate licensing).
The OASIS XML Catalogs v1.1 are fully supported now. In particular, this includes:
XML Types provide the structure and data type information about possible XML files processed by a set of templates (each template is based on a certain XML Type). For more details, please see DocFlex/XML | Documentation | Designing Templates | Defining XML Type | Assigning XML Schemas | xsd.catalogs.
For more details, please see Documentation | Running Generator | Generator GUI | Assigning XML Catalog(s).
XML catalogs are special XML files that allow you to redefine the physical location of the XML files (and other types of files) referred from some other XML files. See also: About XML Catalogs
The "XSDDoc" templates have been modified to support this feature as well.
A new property has been introduced for template sections: "Break Parent Section Block".
When specified, it forces the template interpreter, after the processing of the given section, to break the further processing of the containing it section block according to the property value, which may be one of the following:
"break when section executed"
Note: The section is executed when it has passed its enabling condition (if specified) and the current generator context element complies with the Matching Element Type(s) specified on the section.
Until now, the functionality of the new property was substituted by testing
in the enabling conditions of other sections (located below the given one) one of the generator variables:
'sectionBlock.execSecNone'
or 'sectionBlock.outputSecNone'
.
(Those variables allow you to test if some sections in a section block have been already executed
or produced a non-empty output.)
The old approach works as well now. However, the new one adds clarity, simplifies programming and may substantially improve performance of template applications.
In particular, the new feature allowed us to boost about 15% the performance of the "XSDDoc" template application!
Since this version, DocFlex/XML supports multi-valued template parameters (called also list parameters, for short).
Such parameters allow you to pass into template the whole vector of different values
associated with the same parameter name. This provides a universal mechanism for implementing
a user control over how a set of templates processes a certain type of data (or situations)
that may come in unlimited number of variations.
A list parameter can be specified both in the Parameter Inspector dialog of the Generator GUI
and on the generator command line (using one or many -P
options).
Thanks to some new optimizations, all output generators work 30% faster now.
The EMF image format has been supported. Now, the EMF images can be inserted both in the generated HTML and RTF documents. All supported (and tested) image formats now include: GIF, PNG, JPG, WMF, EMF, BMP.
The automatic wrapping of very long nonbreaking strings within table cells has been improved.
Until this version, such a wrapping was done correctly when the string was generated by the same control. When the entire nonbreaking string was produced by different controls (possibly using different fonts), it was not recognized as a single string and, therefore, was not broken as needed. That caused some summary tables in RTF JavaDoc to expand beyond the page width.
Now, this is fixed!
For more details about that problem with long nonbreaking strings in RTF, see Doclet GUI | RTF Options | Tables | Long string wrapping factor.
The processing of mouse-click events has been reworked so as to show popup menus correctly on different platforms. Until this version, the popup menus actually didn't work on Apple Mac (with its one-button mouse). Now, it is fixed!
The Apache Maven Plugin for DocFlex/XML has been implemented. Now, you can easily integrate DocFlex/XML with the Apache Maven automated build system.
For more details, please see: integrations/maven/index.html
and
Documentation | Integrations | Apache Maven.
A new licensing system has been implemented with the support of multiple licenses (that cover different features within the same software package) and a possibility to attach licenses to particular sets of templates (commercial template application).
The goal is both to allow our customers to pay exactly for what they are willing to use and to provide us with more resources for further development of this software.
Note: Any old commercial licenses for DocFlex/XML will work the same. If you have one, you may install and use it with this version as well.
As the number of template parameters (controlling what is generated) ever grows, the Template Parameter Inspector in its previous form became increasingly cumbersome and difficult to navigate.
This problem has been addressed by introducing a possibility to collapse/expand the parameter group nodes dynamically
(some of which can be preset in the templates to appear initially in the collapsed form;
further, the current collapse/expand state of particular group nodes is saved in the
generator.config
and restored next time).
What is more, now some of the parameter group nodes may themselves serve as the template parameters.
These improvements allow introducing lots of parameters so as to control a particular big template application. Those parameters may be organized in the form of a hierarchical tree, which is both compact and easy to navigate.
This feature may not sound very great, but it was not that easy to implement. In fact, it substantially speeds up the process of designing of templates (which we particularly need ourselves as the primary users of our own tool).
config/xmltypes.config
file)
to any number of XML Type Configuration Files.
Now, a complete XML Type definition (which includes the XML schemas describing the particular
XML data source) can be stored together with the template set based on it and loaded dynamically when needed.
This makes possible to represent a particular template application in the form of a single software unit
that can be easily distributed and deployed by its own.
java.lang.ClassCastException
exception
happening when a schema with unspecified (i.e. global) target namespace imported another schema using
<xs:include>
directive.
In templates, the new image size must be specified in device-independent units (like points). Before that, it was an HTML browser who converted points into pixels, which might be responsible for producing images with unpredictable sizes.
Now, when generating HTML, the DocFlex generator itself converts point size into pixel size according to the DPI value specified in the formatting properties of the given templates (see: Template Designer | File | Properties | Formatting | General | Resolution (DPI)). So, in HTML, the new image size will always be specified in pixels.
Now, all supported image formats include: GIF, PNG, JPG, WMF, BMP
This open source Java library is used by DocFlex/XML (all editions) and included in the package (see Package Contents). Support of the newest version of Apache Xerces will help to integrate DocFlex/XML seamlessly with the latest versions of other important tools (e.g. Apache Ant).
The bug happened when DocFlex/XML home directory was placed inside another directory
whose name contained a space (e.g. 'C:\Program Files\docflex-xml'
).
It caused java.io.FileNotFoundException
during opening the configuration files.
Now, this is working.
align
attribute of an <img>
tag in
a description preformatted with HTML/XHTML markup.
(See Image Control Properties Dialog | Formatting | Image tab).
firstSentence()
function, which extracts the first sentence
from a long description text to be placed in a summary table, has been totally redeveloped.
Now, it recognizes the HTML markup and finds the first sentence boundary according
to the pure text extracted from the original string (i.e. without HTML tags) as well as
stops on any HTML block tag (such as <p>). In the returned string, the original HTML
markup is preserved and unfinished HTML elements are correctly closed.
(See Template Designer | Help | Expression Assistant dialog for more info).
OutputFormat.renderEmbeddedHTML
has been added
to indicate if "Render embedded HTML" format option has been specified for the generator.
Now, this property is used in XSDDoc
templates to better control processing of XHTML in XML schema annotations.
stderr
(by default) or in a separate 'docflex_error.log'
file
(when it is specified with the newly introduced -errlog
option).
GOMIterator.prevItem
and GOMIterator.nextItem
were introduced as well as a method accompanying them:
GOMIterator.itemAt()
.
DSMElement.rawValue
and
DSMAttr.rawValue
. These properties allow accessing the unprocessed
text values of XML elements/attributes directly obtained from the XML files.
You can use this, for instance, like the following:
contextElement.dsmElement.rawValue
(e.g. in the Formula Expression of a Data Control).
For details, see Template Designer | Help | Expression Assistant dialog.
All generator properties accessible within FlexQuery expressions (> 100) as well as all general (148) and XML-specific (18) FlexQuery functions are fully documented now. In total this took writing more than 330 KB of explanations in HTML!
You can find everything at the Template Designer | Help | Assistant dialog.
The first version DocFlex/XML has been released, which started the third and the most advanced product line based on DocFlex Technology. (The previous two, DocFlex/Javadoc and DocFlex/Together, had been already available for more than a year before that.)
Most of the document formatting capabilities was already in place. All processing of XML files was already based on the data type information obtained from DTD or XML Schemas. However, the actual data sources possible to process at once with a single template were limited to only one XML file.
The "Sales Report" and "Alternative to XSLT" samples come from those times.