The importer modules
Since Version 4.4.0 of the Sophora Importer it comes with a model representing Sophora import XML and a module to easily create instances of that model in code.
To programatically create Sophora import XML you need this Maven dependency:
<dependency>
<groupId>com.subshell.sophora</groupId>
<artifactId>com.subshell.sophora.importer.sophoraxml</artifactId>
<version>${sophora.importer.version}</version>
</dependency>
The model itself resides in com.subshell.sophora:com.subshell.sophora.importer.model
but you should usually not directly need this dependency.
What the model represents
The model contains classes each representing the elements of Sophora import XML. You can read about these elements in the other chapters of this part of the documentation. As a rule of thumb if you see an element like <childNodes>
in the XML there should be a class ChildNodes
that is used to represent this element. Child elements have their own respective model classes. Arguments are primitively typed fields of a model class. For example for <childNode name="...">
there is a String getter/setter for ChildNode.name
. In some special cases the model may deviate from this schema.
The model always represents exactly one schema version. It is found in the xmlns
attribute of the document
element. See the overview for details. You can see which schema version the currently used model represents in the class com.subshell.sophora.importer.model.ModelConstants#REPRESENTED_SCHEMA_NAMESPACE
. This makes sure that the classes coherently make up a specific set of features of the Sophora import XML.
Programatically creating XML
The model classes do not have public constructors. Instead, each one has a builder named accordingly. For example to create a Document
use the DocumentBuilder
. This should be the only one you need on top level as all other elements are children of a document and thus not very useful on their own. When using Java this is the preferred API to programatically build Sophora import XML. DSL (explained below) specific extensions reside in the package com.subshell.sophora.importer.model.documents.dsl
which should not be used from Java.
Declarative Kotlin DSL
Because of the deeply nested structure of the XML it is recommended to use a more declarative syntax in Kotlin. We offer a custom DSL (domain specific language) with type safe builders that lets you fluently define Sophora import XML in you code. It almost resembles the XML structure. A simple example looks like this:
buildDocument {
externalId("exampleDocumentToImport")
nodeType("sophora-example-nt:example")
properties {
property("sophora-example:property1") {
singleValue("property1Value")
}
property("sophora-example:property2") {
remove(true)
}
}
fields {
site("example")
structureNode("/import")
idStem("example-")
forceLock {
timeoutInMinutes(10)
retryIntervalInMinutes(2)
}
forceCreate(false)
}
}
Using the XML
The aforementioned DocumentBuilder
or buildDocument()
functions return a Document
model object. This can be used to actually generate XML. In Java use the SophoraXmlCreator
. In Kotlin you may directly use the top level functions buildSophoraXml()
or buildDocumentXml()
in the package com.subshell.sophora.importer.sophoraxml
and below. These functions return a org.redundent.kotlin.xml.Node
which represents the XML itself. There are also *String()
versions of the functions returning pretty printed XML as String.
The easiest way to create an XML String is using buildDocumentXmlString()
because it directly accepts a block of the DSL to build a single document. When using the function with the contents of the example above:
buildDocumentXmlString {
externalId("exampleDocumentToImport")
// ...
}
Results in this valid Sophora import XML:
<?xml version="1.0" encoding="UTF-8"?>
<documents xmlns="http://www.sophoracms.com/import/5.0">
<document externalID="exampleDocumentToImport" nodeType="sophora-example-nt:example">
<properties>
<property name="sophora-example:property1">
<value>property1Value</value>
</property>
<property name="sophora-example:property2" remove="true"></property>
</properties>
<childNodes></childNodes>
<resourceList></resourceList>
<fields>
<site>example</site>
<structureNode>/import</structureNode>
<idstem>example-</idstem>
<forceLock timeout="10" retryInterval="2">true</forceLock>
<forceCreate>false</forceCreate>
<channels>
<enabledChannels></enabledChannels>
<disabledChannels></disabledChannels>
</channels>
</fields>
<instructions>
<lifecycleActivities></lifecycleActivities>
<proposals></proposals>
<stickyNotes></stickyNotes>
</instructions>
</document>
</documents>