ThinXML is a format mapped to XML effortlessly and straightforward, but it contains fewer characters and is more readable. The ThinXML format allows you to leave the closing tags off. Instead of the closing tags, it introduces positioning.
It is somewhat similar to what the Python language is doing compared to other languages.
Many languages use explicit closing for complex constructs, like adding a }
to the end of a block or using the end
keyword.
ThinXML uses spaces to indicate the nesting of the XML tags. To ease the understanding here is a simple example:
project>
modelVersion>4.0.0
name>jamal snippet
packaging>jar
groupId>com.javax0.jamal
artifactId>jamal-snippet
version>2.8.2-SNAPSHOT
parent>
groupId>com.javax0.jamal
artifactId>jamal-parent
version>2.8.2-SNAPSHOT
relativePath>../jamal-parent
It is the same as the standard XML in the following way:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<modelVersion>4.0.0</modelVersion>
<name>jamal snippet</name>
<packaging>jar</packaging>
<groupId>com.javax0.jamal</groupId>
<artifactId>jamal-snippet</artifactId>
<version>2.8.2-SNAPSHOT</version>
<parent>
<groupId>com.javax0.jamal</groupId>
<artifactId>jamal-parent</artifactId>
<version>2.8.2-SNAPSHOT</version>
<relativePath>../jamal-parent</relativePath>
</parent>
</project>
The tags modelVersion
, name
, and so on are all tabbed deeper than project
; thus, they are tags inside the project
tag.
The parent
also has children, which are tabbed deeper.
The tabbing can go back and forth many times.
If we move the groupId
, artifactId
, and version
tags to follow the parent
tag, but with the same tab depth:
project>
modelVersion>4.0.0
name>jamal snippet
packaging>jar
parent>
groupId>com.javax0.jamal
artifactId>jamal-parent
version>2.8.2-SNAPSHOT
relativePath>../jamal-parent
groupId>com.javax0.jamal
artifactId>jamal-snippet
version>2.8.2-SNAPSHOT
we get the following:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<modelVersion>4.0.0</modelVersion>
<name>jamal snippet</name>
<packaging>jar</packaging>
<parent>
<groupId>com.javax0.jamal</groupId>
<artifactId>jamal-parent</artifactId>
<version>2.8.2-SNAPSHOT</version>
<relativePath>../jamal-parent</relativePath>
</parent>
<groupId>com.javax0.jamal</groupId>
<artifactId>jamal-snippet</artifactId>
<version>2.8.2-SNAPSHOT</version>
</project>
The XML text, like the 4.0.0
model version, can be on the same line as the tag, following it, or on the following lines.
project>
modelVersion>4.0.0
name>jamal snippet
packaging>jar
description>
The snippet library for the jamal language.
It also contains the xmlFormat macro that can convert from ThinXML to regular XML.
parent>
groupId>com.javax0.jamal
artifactId>jamal-parent
version>2.8.2-SNAPSHOT
relativePath>../jamal-parent
groupId>com.javax0.jamal
artifactId>jamal-snippet
version>2.8.2-SNAPSHOT
we get the following:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<modelVersion>4.0.0</modelVersion>
<name>jamal snippet</name>
<packaging>jar</packaging>
<description>
The snippet library for the jamal language.
It also contains the xmlFormat macro that can convert from ThinXML to regular XML.
</description>
<parent>
<groupId>com.javax0.jamal</groupId>
<artifactId>jamal-parent</artifactId>
<version>2.8.2-SNAPSHOT</version>
<relativePath>../jamal-parent</relativePath>
</parent>
<groupId>com.javax0.jamal</groupId>
<artifactId>jamal-snippet</artifactId>
<version>2.8.2-SNAPSHOT</version>
</project>
It is essential that the tabulation, even, in this case, has to be the same. Making a mistake and starting the text too much to the left will close the tag.
project>
packaging>jar
description>
The snippet library for the jamal language.
Misaligned text closes the tag.
parent>
groupId>com.javax0.jamal
description>
The parent library for the jamal language.
This misplaced text will close the parent tag also.
relativePath>../jamal-parent
groupId>com.javax0.jamal
artifactId>jamal-snippet
version>2.8.2-SNAPSHOT
will be
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<packaging>jar</packaging>
<description>
The snippet library for the jamal language.
</description>
Misaligned text closes the tag.
<parent>
<groupId>com.javax0.jamal</groupId>
<description>
The parent library for the jamal language.
</description>
</parent>
This misplaced text will close the parent tag also.
<relativePath>../jamal-parent</relativePath>
<groupId>com.javax0.jamal</groupId>
<artifactId>jamal-snippet</artifactId>
<version>2.8.2-SNAPSHOT</version>
</project>
When you place more than one tag on a single line the tabbing counts only for the first one. For example:
jb:project xmlns:jb="https://www.007.com">
jb:films>jb:film id="goldfinger">girls>
jb:girl id="Pussy Galore">
jb:year>1925
jb:girl id="Jill Masterton">
jb:year>1937
jb:girl id="Tilly Masterson">
jb:year>1941
will result in:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<jb:project xmlns:jb="https://www.007.com">
<jb:films>
<jb:film id="goldfinger">
<girls>
<jb:girl id="Pussy Galore">
<jb:year>1925</jb:year>
</jb:girl>
<jb:girl id="Jill Masterton">
<jb:year>1937</jb:year>
</jb:girl>
<jb:girl id="Tilly Masterson">
<jb:year>1941</jb:year>
</jb:girl>
</girls>
</jb:film>
</jb:films>
</jb:project>
This example also demonstrates the use of nameSpaces in ThinXML.
Even though the girl
tags are on a column left to the start of the girls
or film
tags, the tabbing counts only for the first one.
The tags that are on the same line inherit the tag positions of the first tag on the line.
This way, you cannot insert more than one film
tags following the joined line.
To do that you have to split the opening line into separate lines.
project>
films>
film id="goldfinger">
girls>
girl id="Pussy Galore">
year>1925
girl id="Jill Masterton">
year>1937
girl id="Tilly Masterson">
year>1941
film id="casino royale">girls>
girl id="Vesper Lynd">
year>1923
will result in:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<films>
<film id="goldfinger">
<girls>
<girl id="Pussy Galore">
<year>1925</year>
</girl>
<girl id="Jill Masterton">
<year>1937</year>
</girl>
<girl id="Tilly Masterson">
<year>1941</year>
</girl>
</girls>
</film>
<film id="casino royale">
<girls>
<girl id="Vesper Lynd">
<year>1923</year>
</girl>
</girls>
</film>
</films>
</project>
This way the tabbing can be more condensed for deep XML structures, and the same time it is more readable where the individual tags are closed. If you could close a tag standing in line after another tag the readability would suffer.
The tags in ThinXML can also have attributes.
Attributes can be written with "
separators only.
The '
character is not allowed as a separator.
If the attribute value does not have space, then the "
around the value is optional.
project name="prohibited" note="real POM XML does not have attributes">
packaging>jar
description format=plain>
Just some dummy description
parent>
groupId value="com.java0.jamal">
groupId>com.javax0.jamal
artifactId>jamal-snippet
version>2.8.2-SNAPSHOT
All the tags will have attributes surrounded with "
characters in the output.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project name="prohibited" note="real POM XML does not have attributes">
<packaging>jar</packaging>
<description format="plain">
Just some dummy description
</description>
<parent>
<groupId value="com.java0.jamal"/>
</parent>
<groupId>com.javax0.jamal</groupId>
<artifactId>jamal-snippet</artifactId>
<version>2.8.2-SNAPSHOT</version>
</project>
You can also include regular XML tags into think XML. You can manage the file even if the tabbing would otherwise go excessive. For example, the following example has gone with tabbing a bit too far to the right:
project>
modelVersion>4.0.0
name>jamal snippet
packaging>jar
profiles>profile>
id>release
build>plugins>plugin>
groupId>org.apache.maven.plugins
artifactId>maven-gpg-plugin
version>3.0.1
executions>execution>
id>sign-artifacts
phase>verify
goals>goal>sign
It is still correct and works as expected:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<modelVersion>4.0.0</modelVersion>
<name>jamal snippet</name>
<packaging>jar</packaging>
<profiles>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
This example does not achieve the original aim of ThinXML to have readable and straightforward XML structured data. This can be amended including normal XML tags into think XML:
project>
modelVersion>4.0.0
name>jamal snippet
packaging>jar
profiles>profile>
id>release
build>plugins>
<plugin>
groupId>org.apache.maven.plugins
artifactId>maven-gpg-plugin
version>3.0.1
executions>execution>
id>sign-artifacts
phase>verify
goals>goal>sign
</plugin>
It will result in the same as the previous example:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<modelVersion>4.0.0</modelVersion>
<name>jamal snippet</name>
<packaging>jar</packaging>
<profiles>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
The tabulation of the XML part is not essential and is generally ignored. After an opening XML tag, the ThinXML tabbing is reset and gets back to the previous level after the closing XML tag. It can start to the left of the previous tags; the already opened tags will not be closed. The only important rule is that you should align the ThinXML inside the opening and closing tags.
The opened XML tag has to be closed with the closing tag. There is no shorthand for that.
You can embed XML into the ThinXML and ThinXML into the XML into any level deep. For example the previous example can also be written as:
project>
modelVersion>4.0.0
name>jamal snippet
packaging>jar
profiles>profile>
id>release
build>plugins>
<plugin>
groupId>org.apache.maven.plugins
artifactId>maven-gpg-plugin
version>3.0.1
executions>
<execution>
id>sign-artifacts
phase>verify
goals>goal>sign
</execution>
</plugin>
and it still gets the same output:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<modelVersion>4.0.0</modelVersion>
<name>jamal snippet</name>
<packaging>jar</packaging>
<profiles>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
ThinXML can contain CDATA sections.
A CDATA section should start on a separate line and should end on its own line.
The start of the CDATA section is any line that starts with <![CDATA[
.
Then end of the section is the line that ends with ]]>
.
project>
name>jamal snippet
<![CDATA[ you can have text already here
content verbatim anything can come here <>!
and finally something else]]>
packaging>super
is representing the XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<name>jamal snippet</name><![CDATA[ you can have text already here
content verbatim anything can come here <>!
and finally something else]]>
<packaging>super</packaging>
</project>
The position of the <![CDATA[
controls which tags are closed before the CDATA section.
In the example above the CDATA section closes the name
tag, as it appears on the same tabbing level.
If we increase the tabbing it does not close the name
tag.
project>
name>jamal snippet
<![CDATA[ you can have text already here
content verbatim anything can come here <>!
and finally something else]]>
packaging>super
will result in the following output:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<name>jamal snippet<![CDATA[ you can have text already here
content verbatim anything can come here <>!
and finally something else]]></name>
<packaging>super</packaging>
</project>
Although there are overlapping features ThinXML is not Yaml, and it is not the reimplementation of Yaml. ThinXML uses tabbing to structure data, just like Yaml, and it may lure to the fals conclusion that this is just another Yaml. Yaml is an object serialisation format, where you can define data types, circular references, and so on. XML is a data description format. It is one abstraction layer above the objects. XML and Yaml serve different purposes even though you could use the one where the other is used. Both has its purposes, advantages, and disadvantages making them perfect fit for different cases. ThinXML may look like a bit as Yaml because of the tabbing, but it is not.
Note
|
ThinXML is essentially XML. |
It is intended replacing XML as a format, where preferable, and possible to insert the converter into the processing. It is not a new structure. It is still XML expressed in a different way.
The ThinXML converter is implemented in the Jamal Snippet module and can be used with the macro xmlFormat
.
The primary purpose of developing ThinXML was to support Maven POM shortening while keeping it strictly XML.
You can use the Jamal Maven extension (not a plugin!) to instruct Maven to locate and parse the POM via the extension.