Skip to content

Latest commit

 

History

History
618 lines (534 loc) · 17.4 KB

THINXML.adoc

File metadata and controls

618 lines (534 loc) · 17.4 KB

ThinXML Format

Introduction

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:

output
<?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.

ThinXML Tabbing

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:

output
<?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:

output
<?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

output
<?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:

output
<?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:

output
<?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.

Attributes

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.

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>

XML tags in ThinXML

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:

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>

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:

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>

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:

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>

CDATA

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

output
<?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:

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>

ThinXML is not Yaml

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.

Implementation

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.