enhancement
major
minor
major
minor
major
#29974
XML import: <unless-known> cannot import the attributes of a known element without its structure
Observed with 8.0.0-alpha11 (follow-up of #29797) in the ETS import of E-Home (haumacher/ehome #38, doc/tl-todo.md).
<unless-known> skips a known element as a whole. A shared object exported once per language (ETS writes an application program in the language of the installation that exports it) must still gain the texts of the languages it lacks when it is imported again.
Missing:
- an import of the attributes of a known element, and of its descendants (each to the object with that ID), without creating its structure again;
- a condition on the known object (e.g. the languages it already records) that decides whether to skip.
Reproduction: a known object I1 with German texts and the element <Item Id="I1" DefaultLanguage="en-US" Name="..."/>: <unless-known id-attribute="Id"> skips it, so name@en stays unset.
Workaround in E-Home: an own handler <unless-known-program>.
Lösung
<unless-known> gets an optional section <update> that is applied to a known element instead of skipping it:
{{{#!xml <unless-known id-attribute="Id">
<object model-type="..." id-attribute="Id"> ... </object>
<update var="program" arguments="lang"
condition="program -> lang -> !$program.get(ehome:Program#languages).containsElement($lang)">
<set-translation ... />
<dispatch>
<tag name="Child">
<object-ref id-attribute="Id" ignore-unresolved="true">
<set-translation ... />
<dispatch/>
</object-ref>
</tag>
</dispatch>
</update>
</unless-known> }}}
- Unknown ID: the content handlers run (unchanged).
- Known ID without <update>: the element is skipped with its content (unchanged).
- Known ID with <update>: if its predicate condition is not given or evaluates to true, the handlers of <update> are applied with this (and the optional variable var) bound to the known object. No object is created and nothing is linked again; descendants are updated through <object-ref>, which applies its handlers to the existing object with the given ID. Content of the element that the handlers do not consume is skipped, so <update> without <dispatch> updates only the attributes of the known element. If condition evaluates to false, the element is skipped with its content.
- condition receives the known object, followed by the values of the import variables named in arguments (comma-separated). A variable that still refers to an object not yet imported is reported as error and the element is skipped.
- The predicate is named condition (not if), because <if> is the tag of a conditional handler that may occur in the handler list of <update>.
Test
- test.com.top_logic.xio.importer.TestXmlImporter#testUnlessKnownUpdate