:toc:
toc::[]

= XML Plug-in
The CobiGen XML Plug-in comes with an input reader for XML artifacts, XML related trigger and matchers and provides different merge mechanisms for XML result documents.

== Trigger extension
_(since `cobigen-xmlplugin v2.0.0`)_

The XML Plug-in provides a trigger for XML related inputs. It accepts XML documents as input (see `xref:xml-input-reader[XML input reader]`) and provides additional matching and variable assignment mechanisms. The configuration in the `context.xml` for this trigger looks like this:

* type 'xml'
+
.Example of a XML trigger definition.
[source,xml]
----
<trigger id="..." type="xml" templateFolder="...">
    ...
</trigger>
----
+
This trigger type enables XML documents as inputs.


* type `xpath`
+
.Example of a `xpath` trigger definition.
[source,xml]
----
<trigger id="..." type="xpath" templateFolder="...">
    ...
</trigger>
----
+
This trigger type enables XML documents as container inputs, which consists of several sub-documents.

=== Container Matcher type
A `ContainerMatcher` check if the input is a valid container.

* `xpath`: type: `xpath`
+
.Example of a XML trigger definition with a node name matcher.
[source,xml]
----
<trigger id="..." type="xml" templateFolder="...">
    <containerMatcher type="xpath" value="./uml:Model//packagedElement[@xmi:type='uml:Class']">
        ...
    </matcher>
</trigger>
----
+

Before applying any Matcher, this `containerMatcher` checks if the XML file contains a node `uml:Model` with a childnode `packagedElement` which contains an attribute `xmi:type` with the value `uml:Class`.

=== Matcher types
With the trigger you might define matchers, which restrict the input upon specific aspects:

* XML: type `nodename` -> document's root name matching
+
.Example of a XML trigger definition with a node name matcher
[source,xml]
----
<trigger id="..." type="xml" templateFolder="...">
    <matcher type="nodename" value="\D\w*">
        ...
    </matcher>
</trigger>
----
+

This trigger will be enabled if the root name of the declaring input document matches the given regular expression (`value`).

* `xpath`: type: `xpath` -> matching a node with a `xpath` value
+
.Example of a `xpath` trigger definition with a `xpath` matcher.
[source,xml]
----
<trigger id="..." type="xml" templateFolder="...">
    <matcher type="xpath" value="/packagedElement[@xmi:type='uml:Class']">
        ...
    </matcher>
</trigger>
----
+
This trigger will be enabled if the XML file contains a node `/packagedElement` where the `xmi:type` property equals `uml:Class`.

=== Variable Assignment types
Furthermore, it provides the ability to extract information from each input for further processing in the templates. The values assigned by variable assignments will be made available in template and the `destinationPath` of `context.xml` through the namespace `variables.<key>`. The XML Plug-in currently provides only one mechanism:

* type 'constant' -> constant parameter
+
[source,xml]
----
<trigger id="..." type="xml" templateFolder="...">
    <matcher type="nodename" value="\D\w*">
        <variableAssignment type="constant" key="domain" value="restaurant" />
    </matcher>
</trigger>
----

This variable assignment assigns the `value` to the `key` as a constant.

=== XML input reader
The CobiGen XML Plug-in implements an input reader for parsed XML documents. So API user can pass `org.w3c.dom.Document` objects for generation. For getting the right parsed XML inputs you can easily use the `xmlplugin.util.XmlUtil`, which provides static functionality to parse XML files or input streams and get the appropriate `Document` object.

==== Template object
Due to the heterogeneous structure an XML document can have, the XML input reader does not always create exactly the same model structure (in contrast to the java input reader). For example the model's depth differs strongly, according to it's input document. To allow navigational access to the nodes, the model also depends on the document's element's node names. All child elements with unique names, are directly accessible via their names. In addition it is possible to iterate over all child elements with held of the child list `Children`. So it is also possible to access child elements with non unique names.


The XML input reader will create the following object model for template creation (`~EXAMPLEROOT~, ~EXAMPLENODE1~, ~EXAMPLENODE2~, ~EXAMPLEATTR1~,...` are just used here as examples. Of course they will be replaced later by the actual node or attribute names):

* *`\~EXAMPLEROOT~`* ('Map<String, Object>' :: common element structure)
** *`\_nodeName_`* ('String' :: Simple name of the root node)
** *`\_text_`* ('String' :: Concatenated text content (`PCDATA`) of the root node)
** *`TextNodes`* ('List<String>' :: List of all the root's text node contents)
** *`\_at_\~EXAMPLEATTR1~`* ('String' :: String representation of the attribute's value)
** *`\_at_\~EXAMPLEATTR2~`* ('String' :: String representation of the attribute's value)
** *\_at_...*
** *Attributes* ('List<Map<String, Object>>' :: List of the root's attributes
*** at ('Map<String, Object>' :: List element)
**** `*\_attName_* ('String' :: Name of the attribute)`
**** `*\_attValue_* ('String' :: String representation of the attribute's value)`
** *Children* ('List<Map<String, Object>>' :: List of the root's child elements
*** child ('Map<String, Object>' :: List element)
**** ...common element sub structure...
** *`\~EXAMPLENODE1~`* ('Map<String, Object>' :: One of the root's child nodes)
*** ...common element structure...
** *`\~EXAMPLENODE2~`* ('Map<String, Object>' :: One of the root's child nodes)
*** ...common element sub structure...
*** *`\~EXAMPLENODE21~`* ('Map<String, Object>' :: One of the nodes' child nodes)
**** ...common element structure...
*** *`\~EXAMPLENODE...~`*
** *`\~EXAMPLENODE...~`*

In contrast to the java input reader, this XML input reader does currently not provide any additional template methods.

== Merger extensions

The XML plugin uses the link:https://github.com/maybeec/lexeme[`LeXeMe`] merger library to produce semantically correct merge products. The merge strategies can be found in the link:https://github.com/devonfw/cobigen/blob/master/cobigen/cobigen-xmlplugin/src/main/java/com/devonfw/cobigen/xmlplugin/merger/delegates/MergeType.java#L11[`MergeType enum`] and can be configured in the `templates.xml` as a `mergeStrategy` attribute:

* `mergeStrategy xmlmerge`
+
.Example of a template using the `mergeStrategy` `xmlmerge`
[source,xml]
----
<templates>
	<template name="..." destinationPath="..." templateFile="..." mergeStrategy="xmlmerge"/>
</templates>
----

Currently only the document types included in LeXeMe are supported.
On how the merger works consult the link:https://github.com/maybeec/lexeme/wiki[LeXeMe Wiki].
