XML parsing in TL-Script via `XMLImporter`
The declarative XML import (com.top_logic.xio.importer.XmlImporter) can now be exposed as a TL-Script function. This complements the interactive XMLImportCommand (upload dialog): the same import declaration can be invoked from any TL-Script context (buttons, operations, derived values, …) to parse an XML stream into an object graph.
Defining a parse function
The function is a configured, generic method builder (com.top_logic.xio.importer.expr.ParseXml$Builder). Each registration embeds its own import declaration (a DispatchingImporter, i.e. the same XML you would put into an XMLImportCommand's import-definition) and gives the function a name. Register it as a method of the model-search service, e.g. in an application *.config.xml:
{{{#!xml <config service-class="com.top_logic.model.search.expr.config.SearchBuilder">
<instance>
<methods>
<method name="parseLibrary"
class="com.top_logic.xio.importer.expr.ParseXml$Builder">
<dispatch>
<-- the XML-import declaration (tags, objects, properties, linkings) -->
</dispatch>
</method>
</methods>
</instance>
</config> }}}
Because the import declaration is part of the configuration, you typically register one named function per import format.
Calling the function
parseLibrary($data, context: `my.module#ROOT`, transient: false)
Arguments:
- data (mandatory): the XML input as binary data / stream (e.g. the value of an upload field). null yields null.
- context (optional, default none): an object that is made available to the import as its top-level scope (assigned to the implicit this variable; top-level object handlers use it as their scope). This replaces the need to hard-code the import root via an <in-scope expr="…"> handler — the caller supplies it at runtime instead.
- transient (optional, default false): when true, the graph is built from transient objects (post-process it yourself); when false, objects are created persistently in the application model.
- logCreations (optional, default true): log each created object to the application log.
The function returns the top-level object produced by the import.
Transactions (persistent import)
With transient: false the function creates persistent objects in the ambient script transaction (exactly like createObject); it does not open or commit a transaction itself. Invoke it from a transactional context — e.g. a TransactionHandlerByExpression / a command handler configured to run in a transaction — so the changes are committed by the caller.
Typical use: "upload and parse" dialog
To let a user upload a file and run the function, use the standard "script-with-arguments" dialog: a small (transient) input type that declares a binary attribute, opened via the transaction.template, with a TransactionHandlerByExpression whose operation calls the parse function:
form -> model -> parseLibrary(
$form.get(`my.forms:ImportInput#data`),
context: `my.module#ROOT`,
transient: false)
A complete, runnable example is wired into tl-demo (drag-and-drop library grid): input type tl.demo.forms:ImportXmlInput, the registration in demoImportXmlScript.config.xml, and the dialog importLibraryScriptDialog.layout.xml.
Related change: `XMLImportCommand`
For consistency, XMLImportCommand now also provides its target model as the import context (previously the target was only available afterwards via the post-processing function). Existing importers are unaffected; declarations that relied on a hard-coded <in-scope> continue to work, and may now alternatively rely on the supplied context.
----
Original requirement
XMLImporter stellt eine Deklarationssprache für den Import von Objekt-Graphen aus XML bereit. Ein MethodBuilder erzeugt eine TL-Script-Funktion unter Einbeziehung einer Konfiguration. Ein generischer XMLParserMethodBuilder könnte die XML-Import-Deklaration enthalten, und eine Script-Funktion erzeugen, die bei Aufruf aus der Deklaration einen XMLImporter instanziiert und eine übergebenen Strom als XML parst.