TransformXml

The TransformXml Processor is used to transform XML using an XSLT script.

The Processor has the following special features in IGUASU:

  • The latest version of the Saxon XSLT Processor with XSLT 3.0/XPath 3.1 is supported

  • The licensed Saxon EE including its extended features is supplied

  • The XSLT script can be stored directly in a property (in addition to the variants of the external file or of the lookup service) - this makes it easier to use and deploy

  • the direct processing of JSON by fn:json-to-xml() or fn:xml-to-json() is facilitated by the possibility of embedding the incoming JSON in an XML root tag

  • Result documents (xsl:result-document) can be used to:

    • Create relations/outputs of the module

    • Create attributes in the success/failure output(the name of the href must start with a: for this)

  • Use of the NiFi Expression Language in XPath expressions

    • The namespace xmlns:nf="http://nifi.org" is declared for this

    • The method to be called is called el() - e.g. The TransformXml is declared in the namespace .E.g. <xsl:value-of select="nf:el('${UUID()}')"/>

The TransformXml-Processor has a specific editor that allows easy editing of the entire script.

The functions are explained in detail below.

Use of result documents

Prerequisite:

Support result documents

true

In XSLT it looks like this:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
  <xsl:output method="xml" name="xml" indent="yes"/>
  <xsl:output method="text" name="text"/>
  <xsl:template match="/">
    <xsl:result-document href="relationOne" format="xml">
      <resultOne><xsl:copy-of select="/"/></resultOne>
    </xsl:result-document>
    <xsl:result-document href="relationTwo" format="text">
      number of nodes: <xsl:value-of select="count(//*)"/>
    </xsl:result-document>
    <xsl:result-document href="a:attributeOne" format="text">something</xsl:result-document>
    </xsl:template>
</xsl:stylesheet>

The results of the result-documents of relationOne and relationTwo are written to the corresponding relations (outputs) of the Processor. These become available by creating the result-document tags in the script and then saving the script.

The result of the result-document of a:attributeOne is written as an attribute in the success/failure relation due to the prefix a:.

NiFi Expression Language

The NiFi Expression Language can be used both when passing Parameters via Dynamic Properties and within XPath expressions.

EL in Parameters

By adding any Dynamic Property (via the button), the content of this property is passed to the XSLT script as a Parameter (xsl:param). The Expression Language may be used within the value. This can, for example also access the attributes of the incoming FlowFile:

testParam

the filename is ${filename}

This can then be used in the XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
  <xsl:output method="text"/>
  <xsl:param name="testParam"/>
  <xsl:template match="/">
    <xsl:value-of select="$testParam"/>
  </xsl:template>
</xsl:stylesheet>

As the filename in NiFi is typically a UUID, the result is

the filename is 8ec0e87a-56dc-425f-b4c5-1de7f515ddea

EL in XPath expressions*

In order to use the NiFi Expression Language within XPath, this must first be switched on using the corresponding property:

Allow NiFi EL in XPath

true

The namespace must still be set in the XSLT script (xmlns:nf="http://nifi.org"). Then the function (nf:el()) can be called wherever XPath expressions are permitted:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"
xmlns:nf="http://nifi.org">
  <xsl:output method="text"/>
  <xsl:template match="/">
    <xsl:value-of select="nf:el('${UUID()}')"/>
  </xsl:template>
</xsl:stylesheet>

The result is:

2560fc8c-3581-4732-8862-6bb191eb0dcc

In order to use values from the input within the nf:el() execution, these can also be passed as temporary attributes by taking any number of name/value pairs as arguments.

For example, the author of a book can be read from the input as follows and used as an attribute within a NiFi Expression Language function.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:nf="http://nifi.org" version="3.0">
    <xsl:output method="text" />
    <xsl:template match="/">
    <xsl:value-of select="nf:el('${author:toUpper()}', 'author', /library/book[1]/author)" />
    </xsl:template>
</xsl:stylesheet>

JSON processing

To be able to read JSON directly, the corresponding property must be set:

Surround input with <xml> tag

true

This turns the incoming JSON into an XML, to which the XPath 3.0 function can then be applied:

Input JSON:

{
  "name": "Harry",
  "age": 23,
  "address": {
    "city": "London"
  }
}

XSLT script:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:fn="http://www.w3.org/2005/xpath-functions"
                exclude-result-prefixes="fn" version="3.0">
  <xsl:output indent="yes"/>
  <xsl:template match="/">
    <xsl:copy-of select="fn:json-to-xml(.)"/>
  </xsl:template>
</xsl:stylesheet>

Result:

<map xmlns="http://www.w3.org/2005/xpath-functions">
   <string key="name">Harry</string>
   <number key="age">23</number>
   <map key="address">
      <string key="city">London</string>
   </map>
</map>

To turn such an XML structure back into JSON, you can use fn:xml-to-json().