blob: fb507284315ed21717c0b25f97f59f8e1b76b153 [file] [log] [blame]
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 1.5.8">
<meta name="author" content="Apache NiFi Team">
<title>Apache NiFi RecordPath Guide</title>
<style>
/* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */
/* Copyright (C) 2012-2015 Dan Allen, Ryan Waldron and the Asciidoctor Project
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. */
/* Remove the comments around the @import statement below when using this as a custom stylesheet */
@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400";
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}
audio,canvas,video{display:inline-block}
audio:not([controls]){display:none;height:0}
[hidden],template{display:none}
script{display:none!important}
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
body{margin:0}
a{background:transparent}
a:focus{outline:thin dotted}
a:active,a:hover{outline:0}
h1{font-size:2em;margin:.67em 0}
abbr[title]{border-bottom:1px dotted}
b,strong{font-weight:bold}
dfn{font-style:italic}
hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}
mark{background:#ff0;color:#000}
code,kbd,pre,samp{font-family:monospace;font-size:1em}
pre{white-space:pre-wrap}
q{quotes:"\201C" "\201D" "\2018" "\2019"}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sup{top:-.5em}
sub{bottom:-.25em}
img{border:0}
svg:not(:root){overflow:hidden}
figure{margin:0}
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
legend{border:0;padding:0}
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
button,input{line-height:normal}
button,select{text-transform:none}
button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}
button[disabled],html input[disabled]{cursor:default}
input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}
input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}
input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
textarea{overflow:auto;vertical-align:top}
table{border-collapse:collapse;border-spacing:0}
*,*:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
html,body{font-size:100%}
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto}
a:hover{cursor:pointer}
img,object,embed{max-width:100%;height:auto}
object,embed{height:100%}
img{-ms-interpolation-mode:bicubic}
#map_canvas img,#map_canvas embed,#map_canvas object,.map_canvas img,.map_canvas embed,.map_canvas object{max-width:none!important}
.left{float:left!important}
.right{float:right!important}
.text-left{text-align:left!important}
.text-right{text-align:right!important}
.text-center{text-align:center!important}
.text-justify{text-align:justify!important}
.hide{display:none}
.antialiased,body{-webkit-font-smoothing:antialiased}
img{display:inline-block;vertical-align:middle}
textarea{height:auto;min-height:50px}
select{width:100%}
p.lead,.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{font-size:1.21875em;line-height:1.6}
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}
a{color:#2156a5;text-decoration:underline;line-height:inherit}
a:hover,a:focus{color:#1d4b8f}
a img{border:none}
p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
p aside{font-size:.875em;line-height:1.35;font-style:italic}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
h1{font-size:2.125em}
h2{font-size:1.6875em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
h4,h5{font-size:1.125em}
h6{font-size:1em}
hr{border:solid #ddddd8;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}
em,i{font-style:italic;line-height:inherit}
strong,b{font-weight:bold;line-height:inherit}
small{font-size:60%;line-height:inherit}
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9);padding-right: 1px;}
ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
ul,ol,ul.no-bullet,ol.no-bullet{margin-left:1.5em}
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}
ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
ul.square{list-style-type:square}
ul.circle{list-style-type:circle}
ul.disc{list-style-type:disc}
ul.no-bullet{list-style:none}
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
dl dt{margin-bottom:.3125em;font-weight:bold}
dl dd{margin-bottom:1.25em}
abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}
abbr{text-transform:none}
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}
blockquote cite:before{content:"\2014 \0020"}
blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
@media only screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
h1{font-size:2.75em}
h2{font-size:2.3125em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
h4{font-size:1.4375em}}table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}
table thead,table tfoot{background:#f7f8f7;font-weight:bold}
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
.clearfix:before,.clearfix:after,.float-group:before,.float-group:after{content:" ";display:table}
.clearfix:after,.float-group:after{clear:both}
*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}
.keyseq{color:rgba(51,51,51,.8)}
kbd{display:inline-block;color:rgba(0,0,0,.8);font-size:.75em;line-height:1.4;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:-.15em .15em 0 .15em;padding:.2em .6em .2em .5em;vertical-align:middle;white-space:nowrap}
.keyseq kbd:first-child{margin-left:0}
.keyseq kbd:last-child{margin-right:0}
.menuseq,.menu{color:rgba(0,0,0,.8)}
b.button:before,b.button:after{position:relative;top:-1px;font-weight:400}
b.button:before{content:"[";padding:0 3px 0 2px}
b.button:after{content:"]";padding:0 2px 0 3px}
p a>code:hover{color:rgba(0,0,0,.9)}
#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
#header:before,#header:after,#content:before,#content:after,#footnotes:before,#footnotes:after,#footer:before,#footer:after{content:" ";display:table}
#header:after,#content:after,#footnotes:after,#footer:after{clear:both}
#content{margin-top:1.25em}
#content:before{content:none}
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #ddddd8}
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #ddddd8;padding-bottom:8px}
#header .details{border-bottom:1px solid #ddddd8;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}
#header .details span:first-child{margin-left:-.125em}
#header .details span.email a{color:rgba(0,0,0,.85)}
#header .details br{display:none}
#header .details br+span:before{content:"\00a0\2013\00a0"}
#header .details br+span.author:before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
#header .details br+span#revremark:before{content:"\00a0|\00a0"}
#header #revnumber{text-transform:capitalize}
#header #revnumber:after{content:"\00a0"}
#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #ddddd8;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
#toc{border-bottom:1px solid #efefed;padding-bottom:.5em}
#toc>ul{margin-left:.125em}
#toc ul.sectlevel0>li>a{font-style:italic}
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
#toc a{text-decoration:none}
#toc a:active{text-decoration:underline}
#toctitle{color:#7a2518;font-size:1.2em}
@media only screen and (min-width:768px){#toctitle{font-size:1.375em}
body.toc2{padding-left:15em;padding-right:0}
#toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #efefed;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
#toc.toc2 #toctitle{margin-top:0;font-size:1.2em}
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
body.toc2.toc-right{padding-left:0;padding-right:15em}
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #efefed;left:auto;right:0}}@media only screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
#toc.toc2{width:20em}
#toc.toc2 #toctitle{font-size:1.375em}
#toc.toc2>ul{font-size:.95em}
#toc.toc2 ul ul{padding-left:1.25em}
body.toc2.toc-right{padding-left:0;padding-right:20em}}#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
#content #toc>:first-child{margin-top:0}
#content #toc>:last-child{margin-bottom:0}
#footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em}
#footer-text{color:rgba(255,255,255,.8);line-height:1.44}
.sect1{padding-bottom:.625em}
@media only screen and (min-width:768px){.sect1{padding-bottom:1.25em}}.sect1+.sect1{border-top:1px solid #efefed}
#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
#content h1>a.anchor:before,h2>a.anchor:before,h3>a.anchor:before,#toctitle>a.anchor:before,.sidebarblock>.content>.title>a.anchor:before,h4>a.anchor:before,h5>a.anchor:before,h6>a.anchor:before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
table.tableblock>caption.title{white-space:nowrap;overflow:visible;max-width:0}
.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{color:rgba(0,0,0,.85)}
table.tableblock #preamble>.sectionbody>.paragraph:first-of-type p{font-size:inherit}
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
.admonitionblock>table td.icon{text-align:center;width:80px}
.admonitionblock>table td.icon img{max-width:none}
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #ddddd8;color:rgba(0,0,0,.6)}
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}
.exampleblock>.content>:first-child{margin-top:0}
.exampleblock>.content>:last-child{margin-bottom:0}
.sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
.sidebarblock>:first-child{margin-top:0}
.sidebarblock>:last-child{margin-bottom:0}
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8}
.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1}
.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;padding:1em;font-size:.8125em}
.literalblock pre.nowrap,.literalblock pre[class].nowrap,.listingblock pre.nowrap,.listingblock pre[class].nowrap{overflow-x:auto;white-space:pre;word-wrap:normal}
@media only screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}@media only screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}
.listingblock pre.highlightjs{padding:0}
.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}
.listingblock pre.prettyprint{border-width:0}
.listingblock>.content{position:relative}
.listingblock code[data-lang]:before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999}
.listingblock:hover code[data-lang]:before{display:block}
.listingblock.terminal pre .command:before{content:attr(data-prompt);padding-right:.5em;color:#999}
.listingblock.terminal pre .command:not([data-prompt]):before{content:"$"}
table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none}
table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0}
table.pyhltable td.code{padding-left:.75em;padding-right:0}
pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #ddddd8}
pre.pygments .lineno{display:inline-block;margin-right:.25em}
table.pyhltable .linenodiv{background:none!important;padding-right:0!important}
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
.quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em}
.quoteblock blockquote,.quoteblock blockquote p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
.quoteblock blockquote{margin:0;padding:0;border:0}
.quoteblock blockquote:before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
.quoteblock .attribution{margin-top:.5em;margin-right:.5ex;text-align:right}
.quoteblock .quoteblock{margin-left:0;margin-right:0;padding:.5em 0;border-left:3px solid rgba(0,0,0,.6)}
.quoteblock .quoteblock blockquote{padding:0 0 0 .75em}
.quoteblock .quoteblock blockquote:before{display:none}
.verseblock{margin:0 1em 1.25em 1em}
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
.verseblock pre strong{font-weight:400}
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
.quoteblock .attribution br,.verseblock .attribution br{display:none}
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.05em;color:rgba(0,0,0,.6)}
.quoteblock.abstract{margin:0 0 1.25em 0;display:block}
.quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{text-align:left;word-spacing:0}
.quoteblock.abstract blockquote:before,.quoteblock.abstract blockquote p:first-of-type:before{display:none}
table.tableblock{max-width:100%;border-collapse:separate}
table.tableblock td>.paragraph:last-child p>p:last-child,table.tableblock th>p:last-child,table.tableblock td>p:last-child{margin-bottom:0}
table.spread{width:100%}
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
table.grid-all th.tableblock,table.grid-all td.tableblock{border-width:0 1px 1px 0}
table.grid-all tfoot>tr>th.tableblock,table.grid-all tfoot>tr>td.tableblock{border-width:1px 1px 0 0}
table.grid-cols th.tableblock,table.grid-cols td.tableblock{border-width:0 1px 0 0}
table.grid-all *>tr>.tableblock:last-child,table.grid-cols *>tr>.tableblock:last-child{border-right-width:0}
table.grid-rows th.tableblock,table.grid-rows td.tableblock{border-width:0 0 1px 0}
table.grid-all tbody>tr:last-child>th.tableblock,table.grid-all tbody>tr:last-child>td.tableblock,table.grid-all thead:last-child>tr>th.tableblock,table.grid-rows tbody>tr:last-child>th.tableblock,table.grid-rows tbody>tr:last-child>td.tableblock,table.grid-rows thead:last-child>tr>th.tableblock{border-bottom-width:0}
table.grid-rows tfoot>tr>th.tableblock,table.grid-rows tfoot>tr>td.tableblock{border-width:1px 0 0 0}
table.frame-all{border-width:1px}
table.frame-sides{border-width:0 1px}
table.frame-topbot{border-width:1px 0}
th.halign-left,td.halign-left{text-align:left}
th.halign-right,td.halign-right{text-align:right}
th.halign-center,td.halign-center{text-align:center}
th.valign-top,td.valign-top{vertical-align:top}
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
th.valign-middle,td.valign-middle{vertical-align:middle}
table thead th,table tfoot th{font-weight:bold}
tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
p.tableblock>code:only-child{background:none;padding:0}
p.tableblock{font-size:1em}
td>div.verse{white-space:pre}
ol{margin-left:1.75em}
ul li ol{margin-left:1.5em}
dl dd{margin-left:1.125em}
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
ul.unstyled,ol.unnumbered,ul.checklist,ul.none{list-style-type:none}
ul.unstyled,ol.unnumbered,ul.checklist{margin-left:.625em}
ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1em;font-size:.85em}
ul.checklist li>p:first-child>input[type="checkbox"]:first-child{width:1em;position:relative;top:1px}
ul.inline{margin:0 auto .625em auto;margin-left:-1.375em;margin-right:0;padding:0;list-style:none;overflow:hidden}
ul.inline>li{list-style:none;float:left;margin-left:1.375em;display:block}
ul.inline>li>*{display:block}
.unstyled dl dt{font-weight:400;font-style:normal}
ol.arabic{list-style-type:decimal}
ol.decimal{list-style-type:decimal-leading-zero}
ol.loweralpha{list-style-type:lower-alpha}
ol.upperalpha{list-style-type:upper-alpha}
ol.lowerroman{list-style-type:lower-roman}
ol.upperroman{list-style-type:upper-roman}
ol.lowergreek{list-style-type:lower-greek}
.hdlist>table,.colist>table{border:0;background:none}
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
td.hdlist1{padding-right:.75em;font-weight:bold}
td.hdlist1,td.hdlist2{vertical-align:top}
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
.colist>table tr>td:first-of-type{padding:0 .75em;line-height:1}
.colist>table tr>td:last-of-type{padding:.25em 0}
.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}
.imageblock.left,.imageblock[style*="float: left"]{margin:.25em .625em 1.25em 0}
.imageblock.right,.imageblock[style*="float: right"]{margin:.25em 0 1.25em .625em}
.imageblock>.title{margin-bottom:0}
.imageblock.thumb,.imageblock.th{border-width:6px}
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
.image.left{margin-right:.625em}
.image.right{margin-left:.625em}
a.image{text-decoration:none}
span.footnote,span.footnoteref{vertical-align:super;font-size:.875em}
span.footnote a,span.footnoteref a{text-decoration:none}
span.footnote a:active,span.footnoteref a:active{text-decoration:underline}
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em 0;border-width:1px 0 0 0}
#footnotes .footnote{padding:0 .375em;line-height:1.3;font-size:.875em;margin-left:1.2em;text-indent:-1.2em;margin-bottom:.2em}
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none}
#footnotes .footnote:last-of-type{margin-bottom:0}
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
.gist .file-data>table td.line-data{width:99%}
div.unbreakable{page-break-inside:avoid}
.big{font-size:larger}
.small{font-size:smaller}
.underline{text-decoration:underline}
.overline{text-decoration:overline}
.line-through{text-decoration:line-through}
.aqua{color:#00bfbf}
.aqua-background{background-color:#00fafa}
.black{color:#000}
.black-background{background-color:#000}
.blue{color:#0000bf}
.blue-background{background-color:#0000fa}
.fuchsia{color:#bf00bf}
.fuchsia-background{background-color:#fa00fa}
.gray{color:#606060}
.gray-background{background-color:#7d7d7d}
.green{color:#006000}
.green-background{background-color:#007d00}
.lime{color:#00bf00}
.lime-background{background-color:#00fa00}
.maroon{color:#600000}
.maroon-background{background-color:#7d0000}
.navy{color:#000060}
.navy-background{background-color:#00007d}
.olive{color:#606000}
.olive-background{background-color:#7d7d00}
.purple{color:#600060}
.purple-background{background-color:#7d007d}
.red{color:#bf0000}
.red-background{background-color:#fa0000}
.silver{color:#909090}
.silver-background{background-color:#bcbcbc}
.teal{color:#006060}
.teal-background{background-color:#007d7d}
.white{color:#bfbfbf}
.white-background{background-color:#fafafa}
.yellow{color:#bfbf00}
.yellow-background{background-color:#fafa00}
span.icon>.fa{cursor:default}
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
.admonitionblock td.icon .icon-note:before{content:"\f05a";color:#19407c}
.admonitionblock td.icon .icon-tip:before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
.admonitionblock td.icon .icon-warning:before{content:"\f071";color:#bf6900}
.admonitionblock td.icon .icon-caution:before{content:"\f06d";color:#bf3400}
.admonitionblock td.icon .icon-important:before{content:"\f06a";color:#bf0000}
.conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
.conum[data-value] *{color:#fff!important}
.conum[data-value]+b{display:none}
.conum[data-value]:after{content:attr(data-value)}
pre .conum[data-value]{position:relative;top:-.125em}
b.conum *{color:inherit!important}
.conum:not([data-value]):empty{display:none}
h1,h2{letter-spacing:-.01em}
dt,th.tableblock,td.content{text-rendering:optimizeLegibility}
p,td.content{letter-spacing:-.01em}
p strong,td.content strong{letter-spacing:-.005em}
p,blockquote,dt,td.content{font-size:1.0625rem}
p{margin-bottom:1.25rem}
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
.exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
.print-only{display:none!important}
@media print{@page{margin:1.25cm .75cm}
*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}
a{color:inherit!important;text-decoration:underline!important}
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
a[href^="http:"]:not(.bare):after,a[href^="https:"]:not(.bare):after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
abbr[title]:after{content:" (" attr(title) ")"}
pre,blockquote,tr,img{page-break-inside:avoid}
thead{display:table-header-group}
img{max-width:100%!important}
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
#toc{border-bottom:1px solid #ddddd8!important;padding-bottom:0!important}
.sect1{padding-bottom:0!important}
.sect1+.sect1{border:0!important}
#header>h1:first-child{margin-top:1.25rem}
body.book #header{text-align:center}
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em 0}
body.book #header .details{border:0!important;display:block;padding:0!important}
body.book #header .details span:first-child{margin-left:0!important}
body.book #header .details br{display:block}
body.book #header .details br+span:before{content:none!important}
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
.listingblock code[data-lang]:before{display:block}
#footer{background:none!important;padding:0 .9375em}
#footer-text{color:rgba(0,0,0,.6)!important;font-size:.9em}
.hide-on-print{display:none!important}
.print-only{display:block!important}
.hide-for-print{display:none!important}
.show-for-print{display:inherit!important}}
</style>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body class="article">
<div id="header">
<h1>Apache NiFi RecordPath Guide</h1>
<div class="details">
<span id="author" class="author">Apache NiFi Team</span><br>
<span id="email" class="email"><a href="mailto:dev@nifi.apache.org">dev@nifi.apache.org</a></span><br>
</div>
<div id="toc" class="toc">
<div id="toctitle">Table of Contents</div>
<ul class="sectlevel1">
<li><a href="record-path-guide.html#overview">Overview</a></li>
<li><a href="record-path-guide.html#structure">Structure of a RecordPath</a></li>
<li><a href="record-path-guide.html#child">Child Operator</a></li>
<li><a href="record-path-guide.html#descendant">Descendant Operator</a></li>
<li><a href="record-path-guide.html#filters">Filters</a></li>
<li><a href="record-path-guide.html#function_usage">Function Usage</a>
<ul class="sectlevel2">
<li><a href="record-path-guide.html#arrays">Arrays</a></li>
<li><a href="record-path-guide.html#maps">Maps</a></li>
<li><a href="record-path-guide.html#predicates">Predicates</a></li>
</ul>
</li>
<li><a href="record-path-guide.html#functions">Functions</a></li>
<li><a href="record-path-guide.html#standalone_functions">Standalone Functions</a>
<ul class="sectlevel2">
<li><a href="record-path-guide.html#substring">substring</a></li>
<li><a href="record-path-guide.html#substringafter">substringAfter</a></li>
<li><a href="record-path-guide.html#substringafterlast">substringAfterLast</a></li>
<li><a href="record-path-guide.html#substringbefore">substringBefore</a></li>
<li><a href="record-path-guide.html#substringbeforelast">substringBeforeLast</a></li>
<li><a href="record-path-guide.html#replace">replace</a></li>
<li><a href="record-path-guide.html#replaceregex">replaceRegex</a></li>
<li><a href="record-path-guide.html#concat">concat</a></li>
<li><a href="record-path-guide.html#fieldname">fieldName</a></li>
<li><a href="record-path-guide.html#todate">toDate</a></li>
<li><a href="record-path-guide.html#tostring">toString</a></li>
<li><a href="record-path-guide.html#tobytes">toBytes</a></li>
<li><a href="record-path-guide.html#coalesce">coalesce</a></li>
<li><a href="record-path-guide.html#format">format</a></li>
<li><a href="record-path-guide.html#trim">trim</a></li>
<li><a href="record-path-guide.html#touppercase">toUpperCase</a></li>
<li><a href="record-path-guide.html#tolowercase">toLowerCase</a></li>
<li><a href="record-path-guide.html#base64encode">base64Encode</a></li>
<li><a href="record-path-guide.html#base64decode">base64Decode</a></li>
<li><a href="record-path-guide.html#escapejson">escapeJson</a></li>
<li><a href="record-path-guide.html#unescapejson">unescapeJson</a></li>
<li><a href="record-path-guide.html#hash">hash</a></li>
<li><a href="record-path-guide.html#padleft">padLeft</a></li>
<li><a href="record-path-guide.html#padright">padRight</a></li>
<li><a href="record-path-guide.html#uuid5">uuid5</a></li>
</ul>
</li>
<li><a href="record-path-guide.html#filter_functions">Filter Functions</a>
<ul class="sectlevel2">
<li><a href="record-path-guide.html#contains">contains</a></li>
<li><a href="record-path-guide.html#matchesregex">matchesRegex</a></li>
<li><a href="record-path-guide.html#startswith">startsWith</a></li>
<li><a href="record-path-guide.html#endswith">endsWith</a></li>
<li><a href="record-path-guide.html#not">not</a></li>
<li><a href="record-path-guide.html#isempty">isEmpty</a></li>
<li><a href="record-path-guide.html#isblank">isBlank</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div id="content">
<div class="sect1">
<h2 id="overview"><a class="anchor" href="record-path-guide.html#overview"></a>Overview</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Apache NiFi offers a very robust set of Processors that are capable of ingesting, processing,
routing, transforming, and delivering data of any format. This is possible because the NiFi
framework itself is data-agnostic. It doesn&#8217;t care whether your data is a 100-byte JSON message
or a 100-gigabyte video. This is an incredibly powerful feature. However, there are many patterns
that have quickly developed to handle data of differing types.</p>
</div>
<div class="paragraph">
<p>One class of data that is often processed by NiFi is record-oriented data. When we say record-oriented
data, we are often (but not always) talking about structured data such as JSON, CSV, and Avro. There
are many other types of data that can also be represented as "records" or "messages," though. As a result,
a set of Controller Services have been developed for parsing these different data formats and representing
the data in a consistent way by using the RecordReader API. This allows data that has been written in any
data format to be treated the same, so long as there is a RecordReader that is capable of producing a Record
object that represents the data.</p>
</div>
<div class="paragraph">
<p>When we talk about a Record, this is an abstraction that allows us to treat data in the same
way, regardless of the format that it is in. A Record is made up of one or more Fields. Each Field has a name
and a Type associated with it. The Fields of a Record are described using a Record Schema. The Schema indicates
which fields make up a specific type of Record. The Type of a Field will be one of the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>String</p>
</li>
<li>
<p>Boolean</p>
</li>
<li>
<p>Byte</p>
</li>
<li>
<p>Character</p>
</li>
<li>
<p>Short</p>
</li>
<li>
<p>Integer</p>
</li>
<li>
<p>Long</p>
</li>
<li>
<p>BigInt</p>
</li>
<li>
<p>Float</p>
</li>
<li>
<p>Double</p>
</li>
<li>
<p>Date - Represents a Date without a Time component</p>
</li>
<li>
<p>Time - Represents a Time of Day without a Date component</p>
</li>
<li>
<p>Timestamp - Represents a Date and Time</p>
</li>
<li>
<p>Embedded Record - Hierarchical data, such as JSON, can be represented by allowing a field to be of Type Record itself.</p>
</li>
<li>
<p>Choice - A field may be any one of several types.</p>
</li>
<li>
<p>Array - All elements of an array have the same type.</p>
</li>
<li>
<p>Map - All Map Keys are of type String. The Values are of the same type.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Once a stream of data has been converted into Records, the RecordWriter API
allows us to then serialize those Records back into streams of bytes so that they can be passed onto other
systems.</p>
</div>
<div class="paragraph">
<p>Of course, there&#8217;s not much point in reading and writing this data if we aren&#8217;t going to do something with
the data in between. There are several processors that have already been developed for NiFi that provide some
very powerful capabilities for routing, querying, and transforming Record-oriented data. Often times, in order
to perform the desired function, a processor will need input from the user in order to determine which fields
in a Record or which values in a Record should be operated on.</p>
</div>
<div class="paragraph">
<p>Enter the NiFi RecordPath language. RecordPath is intended to be a simple, easy-to-use Domain-Specific Language
(DSL) to specify which fields in a Record we care about or want to access when configuring a processor.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="structure"><a class="anchor" href="record-path-guide.html#structure"></a>Structure of a RecordPath</h2>
<div class="sectionbody">
<div class="paragraph">
<p>A Record in NiFi is made up of (potentially) many fields, and each of these fields could actually be itself a Record. This means that
a Record can be thought of as having a hierarchical, or nested, structure. We talk about an "inner Record" as being the child of the
"outer Record." The child of an inner Record, then, is a descendant of the outer-most Record. Similarly, we can refer to an outer Record
as being an ancestor of an inner Record.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="child"><a class="anchor" href="record-path-guide.html#child"></a>Child Operator</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The RecordPath language is structured in such a way that we are able to easily reference fields of the outer-most Record, or fields of a
child Record, or descendant Record. To accomplish this, we separate the names of the children with a slash character (<code>/</code>), which we
refer to as the <code>child</code> operator. For example,
let&#8217;s assume that we have a Record that is made up of two fields: <code>name</code> and <code>details</code>. Also, assume that <code>details</code> is a field that is
itself a Record and has two Fields: <code>identifier</code> and <code>address</code>. Further, let&#8217;s consider that <code>address</code> is itself a Record that contains
5 fields: <code>number</code>, <code>street</code>, <code>city</code>, <code>state</code>, and <code>zip</code>. An example, written here in JSON for illustrative purposes may look like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"name": "John Doe",
"details": {
"identifier": 100,
"address": {
"number": "123",
"street": "5th Avenue",
"city": "New York",
"state": "NY",
"zip": "10020"
}
}
}</pre>
</div>
</div>
<div class="paragraph">
<p>We can reference the <code>zip</code> field by using the RecordPath: <code>/details/address/zip</code>. This tells us that we want to use the <code>details</code> field of
the "root" Record. We then want to reference the <code>address</code> field of the child Record and the <code>zip</code> field of that Record.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="descendant"><a class="anchor" href="record-path-guide.html#descendant"></a>Descendant Operator</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In addition to providing an explicit path to reach the <code>zip</code> field, it may sometimes be useful to reference the <code>zip</code> field without knowing
the full path. In such a case, we can use the <code>descendant</code> operator (<code>//</code>) instead of the <code>child</code> operator (<code>/</code>). To reach the same <code>zip</code>
field as above, we can accomplish this by simply using the path <code>//zip</code>.</p>
</div>
<div class="paragraph">
<p>There is a very important distinction, though, between the <code>child</code> operator and the <code>descendant</code> operator: the <code>descendant</code> operator may match
many fields, whereas the <code>child</code> operator will match at most one field. To help understand this, consider the following Record:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"name": "John Doe",
"workAddress": {
"number": "123",
"street": "5th Avenue",
"city": "New York",
"state": "NY",
"zip": "10020"
},
"homeAddress": {
"number": "456",
"street": "116th Avenue",
"city": "New York",
"state": "NY",
"zip": "11697"
}
}</pre>
</div>
</div>
<div class="paragraph">
<p>Now, if we use the RecordPath <code>/workAddress/zip</code>, we will be referencing the <code>zip</code> field that has a value of "10020." The RecordPath <code>/homeAddress/zip</code> will
reference the <code>zip</code> field that has a value of "11697." However, the RecordPath <code>//zip</code> will reference both of these fields.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="filters"><a class="anchor" href="record-path-guide.html#filters"></a>Filters</h2>
<div class="sectionbody">
<div class="paragraph">
<p>With the above examples and explanation, we are able to easily reference a specific field within a Record. However, in real scenarios, the data is rarely as
simple as in the examples above. Often times, we need to filter out or refine which fields we are referencing. Examples of when we might want to do this are
when we reference an Array field and want to only reference some of the elements in the array; when we reference a Map field and want to reference one or a few
specific entries in the Map; or when we want to reference a Record only if it adheres to some criteria. We can accomplish this by providing our criteria to the
RecordPath within square brackets (using the <code>[</code> and <code>]</code> characters). We will go over each of these cases below.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="function_usage"><a class="anchor" href="record-path-guide.html#function_usage"></a>Function Usage</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In addition to retrieving a field from a Record, as outlined above in the <a href="record-path-guide.html#filters">Filters</a> section, we sometimes need to refine which fields we want to select. Or we
may want to return a modified version of a field. To do this, we rely on functions. The syntax for a function is &lt;function name&gt; &lt;open parenthesis&gt; &lt;args&gt; &lt;close parenthesis&gt;,
where &lt;args&gt; represents one or more arguments separated by commas. An argument may be a string literal (such as <code>'hello'</code>) or a number literal (such as <code>48</code>), or could be
a relative or absolute RecordPath (such as <code>./name</code> or <code>/id</code>). Additionally, we can use functions within a filter. For example, we could use a RecordPath such as
<code>/person[ isEmpty('name') ]/id</code> to retrieve the <code>id</code> field of any person whose name is empty. A listing of functions that are available and their corresponding documentation
can be found below in the <a href="record-path-guide.html#functions">Functions</a> section.</p>
</div>
<div class="sect2">
<h3 id="arrays"><a class="anchor" href="record-path-guide.html#arrays"></a>Arrays</h3>
<div class="paragraph">
<p>When we reference an Array field, the value of the field may be an array that contains several elements, but we may want only a few of those elements. For example,
we may want to reference only the first element; only the last element; or perhaps the first, second, third, and last elements. We can reference a specific element simply by
using the index of the element within square brackets (the index is 0-based). So let us consider a modified version of the Record above:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"name": "John Doe",
"addresses": [
"work": {
"number": "123",
"street": "5th Avenue",
"city": "New York",
"state": "NY",
"zip": "10020"
},
"home": {
"number": "456",
"street": "116th Avenue",
"city": "New York",
"state": "NY",
"zip": "11697"
}
]
}</pre>
</div>
</div>
<div class="paragraph">
<p>We can now reference the first element in the <code>addresses</code> array by using the RecordPath <code>/addresses[0]</code>. We can access the second element using the RecordPath <code>/addresses[1]</code>.
There may be times, though, that we don&#8217;t know how many elements will exist in the array. So we can use negative indices to count backward from the end of the array. For example,
we can access the last element as <code>/addresses[-1]</code> or the next-to-last element as <code>/addresses[-2]</code>. If we want to reference several elements, we can use a comma-separated list of
elements, such as <code>/addresses[0, 1, 2, 3]</code>. Or, to access elements 0 through 8, we can use the <code>range</code> operator (<code>..</code>), as in <code>/addresses[0..8]</code>. We can also mix these, and reference
all elements by using the syntax <code>/addresses[0..-1]</code> or even <code>/addresses[0, 1, 4, 6..-1]</code>. Of course, not all of the indices referenced here will match on the Record above, because
the <code>addresses</code> array has only 2 elements. The indices that do not match will simply be skipped.</p>
</div>
</div>
<div class="sect2">
<h3 id="maps"><a class="anchor" href="record-path-guide.html#maps"></a>Maps</h3>
<div class="paragraph">
<p>Similar to an Array field, a Map field may actually consist of several different values. RecordPath gives us the ability to select a set of values based on their keys.
We do this by using a quoted String within square brackets. As an example, let&#8217;s re-visit our original Record from above:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"name": "John Doe",
"details": {
"identifier": 100,
"address": {
"number": "123",
"street": "5th Avenue",
"city": "New York",
"state": "NY",
"zip": "10020"
}
}
}</pre>
</div>
</div>
<div class="paragraph">
<p>Now, though, let&#8217;s consider that the Schema that is associated with the Record indicates that the <code>address</code> field is not a Record but rather a <code>Map</code> field.
In this case, if we attempt to reference the <code>zip</code> using the RecordPath <code>/details/address/zip</code> the RecordPath will not match because the <code>address</code> field is not a Record
and therefore does not have any Child Record named <code>zip</code>. Instead, it is a Map field with keys and values of type String.
Unfortunately, when looking at JSON this may seem a bit confusing because JSON does not truly have a Type system. When we convert the JSON into a Record object in order
to operate on the data, though, this distinction can be important.</p>
</div>
<div class="paragraph">
<p>In the case laid out above, we can still access the <code>zip</code> field using RecordPath. We must now use the a slightly different syntax, though: <code>/details/address['zip']</code>. This
is telling the RecordPath that we want to access the <code>details</code> field at the highest level. We then want to access its <code>address</code> field. Since the <code>address</code> field is a <code>Map</code>
field we can use square brackets to indicate that we want to specify a Map Key, and we can then specify the key in quotes.</p>
</div>
<div class="paragraph">
<p>Further, we can select more than one Map Key, using a comma-separated list: <code>/details/address['city', 'state', 'zip']</code>. We can also select all of the fields, if we want,
using the Wildcard operator (<code>*</code>): <code>/details/address[*]</code>. Map fields do not contain any sort of ordering, so it is not possible to reference the keys by numeric indices.</p>
</div>
</div>
<div class="sect2">
<h3 id="predicates"><a class="anchor" href="record-path-guide.html#predicates"></a>Predicates</h3>
<div class="paragraph">
<p>Thus far, we have discussed two different types of filters. Each of them allows us to select one or more elements out from a field that allows for many values.
Often times, though, we need to apply a filter that allows us to restrict which Record fields are selected. For example, what if we want to select the <code>zip</code> field but
only for an <code>address</code> field where the state is not New York? The above examples do not give us any way to do this.</p>
</div>
<div class="paragraph">
<p>RecordPath provides the user the ability to specify a Predicate. A Predicate is simply a filter that can be applied to a field in order to determine whether or not the
field should be included in the results. Like other filters, a Predicate is specified within square brackets. The syntax of the Predicate is
<code>&lt;Relative RecordPath&gt; &lt;Operator&gt; &lt;Expression&gt;</code>. The <code>Relative RecordPath</code> works just like any other RecordPath but must start with a <code>.</code> (to reference the current field)
or a <code>..</code> (to reference the current field&#8217;s parent) instead of a slash and references
fields relative to the field that the Predicate applies to. The <code>Operator</code> must be one of:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Equals (<code>=</code>)</p>
</li>
<li>
<p>Not Equal (<code>!=</code>)</p>
</li>
<li>
<p>Greater Than (<code>&gt;</code>)</p>
</li>
<li>
<p>Greater Than or Equal To (<code>&gt;=</code>)</p>
</li>
<li>
<p>Less Than (<code>&lt;</code>)</p>
</li>
<li>
<p>Less Than or Equal To (<code>&lt;=</code>)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The <code>Expression</code> can be a literal value such as <code>50</code> or <code>Hello</code> or can be another RecordPath.</p>
</div>
<div class="paragraph">
<p>To illustrate this, let&#8217;s take the following Record as an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"name": "John Doe",
"workAddress": {
"number": "123",
"street": "5th Avenue",
"city": "New York",
"state": "NY",
"zip": "10020"
},
"homeAddress": {
"number": "456",
"street": "Grand St",
"city": "Jersey City",
"state": "NJ",
"zip": "07304"
},
"details": {
"position": "Dataflow Engineer",
"preferredState": "NY"
}
}</pre>
</div>
</div>
<div class="paragraph">
<p>Now we can use a Predicate to choose only the fields where the state is not New York. For example, we can use <code>/*[./state != 'NY']</code>. This will select any Record field
that has a <code>state</code> field if the state does not have a value of "NY". Note that the <code>details</code> Record will not be returned because it does not have a field named <code>state</code>.
So in this example, the RecordPath will select only the <code>homeAddress</code> field. Once we have selected that field, we can continue on with our RecordPath. As we stated
above, we can select the <code>zip</code> field: <code>/*[./state != 'NY']/zip</code>. This RecordPath will result in selecting the <code>zip</code> field only from the <code>homeAddress</code> field.</p>
</div>
<div class="paragraph">
<p>We can also compare the value in one field with the value in another field. For example, we can select the address that is in the person&#8217;s preferred state by using
the RecordPath <code>/*[./state = /details/preferredState]</code>. In this example, this RecordPath will retrieve the <code>workAddress</code> field because its <code>state</code> field matches the
value of the <code>preferredState</code> field.</p>
</div>
<div class="paragraph">
<p>Additionally, we can write a RecordPath that references the "city" field of any record whose state is "NJ" by using the parent operator (<code>..</code>): <code>/*/city[../state = 'NJ']</code>.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="functions"><a class="anchor" href="record-path-guide.html#functions"></a>Functions</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In the <a href="record-path-guide.html#function_usage">Function Usage</a> section above, we describe how and why to use a function in RecordPath. Here, we will describe the different functions that are available,
what they do, and how they work. Functions can be divided into two groups: <a href="record-path-guide.html#standalone_functions">Standalone Functions</a>, which can be the 'root' of a RecordPath, such as <code>substringAfter( /name, ' ' )</code>
and <a href="record-path-guide.html#filter_functions">Filter Functions</a>, which are to be used as a filter, such as <code>/name[ contains('John') ]</code>. A Standalone Function can also be used within a filter but does not return a <code>boolean</code>
(<code>true</code> or <code>false</code> value) and therefore cannot itself be an entire filter. For example, we can use a path such as <code>/name[ substringAfter(., ' ') = 'Doe']</code> but we cannot simply use
<code>/name[ substringAfter(., ' ') ]</code> because doing so doesn&#8217;t really make sense, as filters must be boolean values.</p>
</div>
<div class="paragraph">
<p>Unless otherwise noted, all of the examples below are written to operate on the following Record:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"name": "John Doe",
"workAddress": {
"number": "123",
"street": "5th Avenue",
"city": "New York",
"state": "NY",
"zip": "10020"
},
"homeAddress": {
"number": "456",
"street": "Grand St",
"city": "Jersey City",
"state": "NJ",
"zip": "07304"
},
"details": {
"position": "Dataflow Engineer",
"preferredState": "NY",
"employer": "",
"vehicle": null,
"phrase": " "
}
}</pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="standalone_functions"><a class="anchor" href="record-path-guide.html#standalone_functions"></a>Standalone Functions</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="substring"><a class="anchor" href="record-path-guide.html#substring"></a>substring</h3>
<div class="paragraph">
<p>The substring function returns a portion of a String value. The function requires 3 arguments: The value to take a portion of, the 0-based start index (inclusive),
and the 0-based end index (exclusive). The start index and end index can be <code>0</code> to indicate the first character of a String, a positive integer to indicate the nth index
into the string, or a negative integer. If the value is a negative integer, say <code>-n</code>, then this represents the <code>n`th character for the end. A value of `-1</code> indicates the last
character in the String. So, for example, <code>substring( 'hello world', 0, -1 )</code> means to take the string <code>hello</code>, and return characters 0 through the last character, so the return
value will be <code>hello world</code>.</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>substring( /name, 0, -1 )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>substring( /name, 0, -5 )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>substring( /name, 1000, 1005 )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;empty string&gt;</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>substring( /name, 0, 1005)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>substring( /name, -50, -1)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;empty string&gt;</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="substringafter"><a class="anchor" href="record-path-guide.html#substringafter"></a>substringAfter</h3>
<div class="paragraph">
<p>Returns the portion of a String value that occurs after the first occurrence of some other value.</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>substringAfter( /name, ' ' )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Doe</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>substringAfter( /name, 'o' )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">hn Doe</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>substringAfter( /name, '' )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>substringAfter( /name, 'xyz' )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="substringafterlast"><a class="anchor" href="record-path-guide.html#substringafterlast"></a>substringAfterLast</h3>
<div class="paragraph">
<p>Returns the portion of a String value that occurs after the last occurrence of some other value.</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>substringAfterLast( /name, ' ' )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Doe</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>substringAfterLast( /name, 'o' )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">e</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>substringAfterLast( /name, '' )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>substringAfterLast( /name, 'xyz' )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="substringbefore"><a class="anchor" href="record-path-guide.html#substringbefore"></a>substringBefore</h3>
<div class="paragraph">
<p>Returns the portion of a String value that occurs before the first occurrence of some other value.</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>substringBefore( /name, ' ' )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>substringBefore( /name, 'o' )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">J</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>substringBefore( /name, '' )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>substringBefore( /name, 'xyz' )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="substringbeforelast"><a class="anchor" href="record-path-guide.html#substringbeforelast"></a>substringBeforeLast</h3>
<div class="paragraph">
<p>Returns the portion of a String value that occurs before the last occurrence of some other value.</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>substringBeforeLast( /name, ' ' )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>substringBeforeLast( /name, 'o' )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John D</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>substringBeforeLast( /name, '' )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>substringBeforeLast( /name, 'xyz' )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="replace"><a class="anchor" href="record-path-guide.html#replace"></a>replace</h3>
<div class="paragraph">
<p>Replaces all occurrences of a String with another String.</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>replace( /name, 'o', 'x' )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Jxhn Dxe</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>replace( /name, 'o', 'xyz' )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Jxyzhn Dxyze</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>replace( /name, 'xyz', 'zyx' )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>replace( /name, 'Doe', /workAddress/city )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John New York</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="replaceregex"><a class="anchor" href="record-path-guide.html#replaceregex"></a>replaceRegex</h3>
<div class="paragraph">
<p>Evaluates a Regular Expression against the contents of a String value and replaces any match with another value.
This function requires 3 arguments: the String to run the regular expression against, the regular expression to run,
and the replacement value. The replacement value may optionally use back-references, such as <code>$1</code> and <code>${named_group}</code></p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>replaceRegex( /name, 'o', 'x' )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Jxhn Dxe</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>replaceRegex( /name, 'o', 'xyz' )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Jxyzhn Dxyze</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>replaceRegex( /name, 'xyz', 'zyx' )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>replaceRegex( /name, '\s+.*', /workAddress/city )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John New York</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>replaceRegex(/name, '([JD])', '$1x')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Jxohn Dxoe</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>replaceRegex(/name, '(?&lt;hello&gt;[JD])', '${hello}x')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Jxohn Dxoe</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="concat"><a class="anchor" href="record-path-guide.html#concat"></a>concat</h3>
<div class="paragraph">
<p>Concatenates all the arguments together.</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>concat( /name, ' lives in ', /homeAddress/city )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe lives in Jersey City</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="fieldname"><a class="anchor" href="record-path-guide.html#fieldname"></a>fieldName</h3>
<div class="paragraph">
<p>Normally, when a path is given to a particular field in a Record, what is returned is the value of that field. It
can sometimes be useful, however, to obtain the name of the field instead of the value. To do this, we can use the
<code>fieldName</code> function.</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>fieldName(//city/..)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>workAddress</code> and <code>homeAddress</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>//city[not(startsWith(fieldName(..), 'work'))]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Jersey City</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>In the above example, the first RecordPath returns two separate field names: "workAddress" and "homeAddress". The second
RecordPath, in contrast, returns the value of a "city" field and uses the <code>fieldName</code> function as a predicate. The second
RecordPath finds a "city" field whose parent does not have a name that begins with "work". This means that it will return
the value of the "city" field whose parent is "homeAddress" but not the value of the "city" field whose parent is "workAddress".</p>
</div>
</div>
<div class="sect2">
<h3 id="todate"><a class="anchor" href="record-path-guide.html#todate"></a>toDate</h3>
<div class="paragraph">
<p>Converts a String to a date. For example, given a schema such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"type": "record",
"name": "events",
"fields": [
{ "name": "name", "type": "string" },
{ "name": "eventDate", "type" : "string"}
]
}</pre>
</div>
</div>
<div class="paragraph">
<p>and a record such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"name" : "My Event",
"eventDate" : "2017-10-20T00:00:00Z"
}</pre>
</div>
</div>
<div class="paragraph">
<p>The following record path would parse the eventDate field into a Date:</p>
</div>
<div class="paragraph">
<p><code>toDate( /eventDate, "yyyy-MM-dd&#8217;T&#8217;HH:mm:ss&#8217;Z'")</code></p>
</div>
<div class="paragraph">
<p><code>toDate( /eventDate, "yyyy-MM-dd&#8217;T&#8217;HH:mm:ss&#8217;Z'", "GMT+8:00")</code></p>
</div>
</div>
<div class="sect2">
<h3 id="tostring"><a class="anchor" href="record-path-guide.html#tostring"></a>toString</h3>
<div class="paragraph">
<p>Converts a value to a String, using the given character set if the input type is "bytes". For example,
given a schema such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"type": "record",
"name": "events",
"fields": [
{ "name": "name", "type": "string" },
{ "name": "bytes", "type" : "bytes"}
]
}</pre>
</div>
</div>
<div class="paragraph">
<p>and a record such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"name" : "My Event",
"bytes" : "Hello World!"
}</pre>
</div>
</div>
<div class="paragraph">
<p>The following record path would parse the bytes field into a String:</p>
</div>
<div class="paragraph">
<p><code>toString( /bytes, "UTF-8")</code></p>
</div>
</div>
<div class="sect2">
<h3 id="tobytes"><a class="anchor" href="record-path-guide.html#tobytes"></a>toBytes</h3>
<div class="paragraph">
<p>Converts a String to byte[], using the given character set. For example, given a schema such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"type": "record",
"name": "events",
"fields": [
{ "name": "name", "type": "string" },
{ "name": "s", "type" : "string"}
]
}</pre>
</div>
</div>
<div class="paragraph">
<p>and a record such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"name" : "My Event",
"s" : "Hello World!"
}</pre>
</div>
</div>
<div class="paragraph">
<p>The following record path would convert the String field into a byte array using UTF-16 encoding:</p>
</div>
<div class="paragraph">
<p><code>toBytes( /s, "UTF-16")</code></p>
</div>
</div>
<div class="sect2">
<h3 id="coalesce"><a class="anchor" href="record-path-guide.html#coalesce"></a>coalesce</h3>
<div class="paragraph">
<p>Returns the first value from the given arguments that is non-null. For example, given a record such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"id": null,
"name": "John Doe"
}</pre>
</div>
</div>
<div class="paragraph">
<p>The following record path would return "John Doe":</p>
</div>
<div class="paragraph">
<p><code>coalesce(/id, /name)</code></p>
</div>
<div class="paragraph">
<p>Given the record:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"id": "1234",
"name": null
}</pre>
</div>
</div>
<div class="paragraph">
<p>The same record path would return "1234".</p>
</div>
<div class="paragraph">
<p>Given the record:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"id": null,
"name": null
}</pre>
</div>
</div>
<div class="paragraph">
<p>The record path would return <code>null</code>.</p>
</div>
<div class="paragraph">
<p>Given the record:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"id": "null",
"name": "John Doe"
}</pre>
</div>
</div>
<div class="paragraph">
<p>The record path would return the String "null". Note here the very important difference in that the <code>id</code>
field does not have a null value but rather the value of the field is the literal string "null".</p>
</div>
<div class="paragraph">
<p>Given the record:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"name": null
}</pre>
</div>
</div>
<div class="paragraph">
<p>The record path would return <code>null</code>. Given that the <code>id</code> field is not present, it is treated as a <code>null</code> value.</p>
</div>
<div class="paragraph">
<p>Given the record:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"id": "1234",
"name": "John Doe"
}</pre>
</div>
</div>
<div class="paragraph">
<p>The record path would return "1234". However, the record path <code>coalesce(/name, /id)</code> would return "John Doe" because
both fields given are non-null, so the <code>coalesce</code> function returns the first value that is referenced in its arguments,
not the first value that is encountered in the Record itself.</p>
</div>
</div>
<div class="sect2">
<h3 id="format"><a class="anchor" href="record-path-guide.html#format"></a>format</h3>
<div class="paragraph">
<p>Converts a Date to a String in the given format with an optional time zone. The function defaults to the system local
time zone when the second argument is not provided.</p>
</div>
<div class="paragraph">
<p>The first argument to this function must be a Date or a Number, and the second argument must be a format String that
follows the Java SimpleDateFormat, and the third argument, optional, must be a format String that
either an abbreviation such as "PST", a full name such as "America/Los_Angeles", or a custom ID such as "GMT-8:00"</p>
</div>
<div class="paragraph">
<p>For example, given a schema such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"type": "record",
"name": "events",
"fields": [
{ "name": "name", "type": "string" },
{ "name": "eventDate", "type" : { "type" : "long", "logicalType" : "timestamp-millis" } }
]
}</pre>
</div>
</div>
<div class="paragraph">
<p>and a record such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"name" : "My Event",
"eventDate" : 1508457600000
}</pre>
</div>
</div>
<div class="paragraph">
<p>The following record path expressions would format the date as a String:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>format( /eventDate, "yyyy-MM-dd&#8217;T&#8217;HH:mm:ss&#8217;Z'")</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2017-10-20T00:00:00Z</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>format( /eventDate, "yyyy-MM-dd")</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2017-10-20</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>format( /eventDate, "yyyy-MM-dd HH:mm:ss Z", "GMT+8:00")</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2017-10-20 08:00:00 +0800</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>format( /eventDate, "yyyy-MM-dd", "GMT+8:00")</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2017-10-20</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>In the case where the field is declared as a String, the toDate function must be called before formatting.</p>
</div>
<div class="paragraph">
<p>For example, given a schema such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"type": "record",
"name": "events",
"fields": [
{ "name": "name", "type": "string" },
{ "name": "eventDate", "type" : "string"}
]
}</pre>
</div>
</div>
<div class="paragraph">
<p>and a record such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"name" : "My Event",
"eventDate" : "2017-10-20T00:00:00Z"
}</pre>
</div>
</div>
<div class="paragraph">
<p>The following record path expression would re-format the date String:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>format( toDate(/eventDate, "yyyy-MM-dd&#8217;T&#8217;HH:mm:ss&#8217;Z'"), 'yyyy-MM-dd')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2017-10-20</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="trim"><a class="anchor" href="record-path-guide.html#trim"></a>trim</h3>
<div class="paragraph">
<p>Removes whitespace from the start and end of a string.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"type": "record",
"name": "events",
"fields": [
{ "name": "name", "type": "string" }
]
}</pre>
</div>
</div>
<div class="paragraph">
<p>and a record such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"name" : " John Smith "
}</pre>
</div>
</div>
<div class="paragraph">
<p>The following record path expression would remove extraneous whitespace:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>trim(/name)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Smith</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="touppercase"><a class="anchor" href="record-path-guide.html#touppercase"></a>toUpperCase</h3>
<div class="paragraph">
<p>Change the entire String to upper case</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"type": "record",
"name": "events",
"fields": [
{ "name": "fullName", "type": "string" }
]
}</pre>
</div>
</div>
<div class="paragraph">
<p>and a record such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"fullName" : "john smith"
}</pre>
</div>
</div>
<div class="paragraph">
<p>The following record path expression would remove extraneous whitespace:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>toUpperCase(/name)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">JOHN SMITH</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="tolowercase"><a class="anchor" href="record-path-guide.html#tolowercase"></a>toLowerCase</h3>
<div class="paragraph">
<p>Changes the entire string to lower case.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"type": "record",
"name": "events",
"fields": [
{ "name": "message", "type": "string" }
]
}</pre>
</div>
</div>
<div class="paragraph">
<p>and a record such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"name" : "hEllO wORLd"
}</pre>
</div>
</div>
<div class="paragraph">
<p>The following record path expression would remove extraneous whitespace:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>trim(/message)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">hello world</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="base64encode"><a class="anchor" href="record-path-guide.html#base64encode"></a>base64Encode</h3>
<div class="paragraph">
<p>Converts a String or byte[] using Base64 encoding, using the UTF-8 character set. For example, given a schema such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"type": "record",
"name": "events",
"fields": [
{ "name": "name", "type": "string" }
]
}</pre>
</div>
</div>
<div class="paragraph">
<p>and a record such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"name" : "John"
}</pre>
</div>
</div>
<div class="paragraph">
<p>The following record path expression would encode the String using Base64:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>base64Encode(/name)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Sm9obg==</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="base64decode"><a class="anchor" href="record-path-guide.html#base64decode"></a>base64Decode</h3>
<div class="paragraph">
<p>Decodes a Base64-encoded String or byte[]. For example, given a schema such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"type": "record",
"name": "events",
"fields": [
{ "name": "name", "type": "string" }
]
}</pre>
</div>
</div>
<div class="paragraph">
<p>and a record such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"name" : "Sm9obg=="
}</pre>
</div>
</div>
<div class="paragraph">
<p>The following record path expression would decode the String using Base64:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>base64Decode(/name)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="escapejson"><a class="anchor" href="record-path-guide.html#escapejson"></a>escapeJson</h3>
<div class="paragraph">
<p>JSON Stringifies a Record, Array or simple field (e.g. String), using the UTF-8 character set. For example, given a schema such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"type": "record",
"name": "events",
"fields": [{
"name": "person",
"type": "record",
"fields": [
{ "name": "name", "type": "string" },
{ "name": "age", "type": "int" }
]
}]
}</pre>
</div>
</div>
<div class="paragraph">
<p>and a record such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"person": {
"name" : "John",
"age" : 30
}
}</pre>
</div>
</div>
<div class="paragraph">
<p>The following record path expression would convert the record into an escaped JSON String:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>escapeJson(/person)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">"{\"person\":{\"name\":\"John\",\"age\":30}}"</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>escapeJson(/person/firstName)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">"\"John\""</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>escapeJson(/person/age)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">"30"</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="unescapejson"><a class="anchor" href="record-path-guide.html#unescapejson"></a>unescapeJson</h3>
<div class="paragraph">
<p>Converts a stringified JSON element to a Record, Array or simple field (e.g. String), using the UTF-8 character set. For example, given a schema such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"type": "record",
"name": "events",
"fields": [{
"name": "person",
"type": "record",
"fields": [
{ "name": "name", "type": "string" },
{ "name": "age", "type": "int" }
]
}]
}</pre>
</div>
</div>
<div class="paragraph">
<p>and a record such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"json_str": "{\"person\":{\"name\":\"John\",\"age\":30}}"
}</pre>
</div>
</div>
<div class="paragraph">
<p>The following record path expression would populate the record with unescaped JSON fields:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>unescapeJson(/json_str)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">{"person": {"name": "John", "age": 30}}"</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>Given a record such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"json_str": "\"John\""
}</pre>
</div>
</div>
<div class="paragraph">
<p>The following record path expression would return:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>unescapeJson(/json_str)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">"John"</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>Note that the target schema must be pre-defined if the unescaped JSON is to be set in a Record&#8217;s fields - Infer Schema will not currently do this automatically.</p>
</div>
</div>
<div class="sect2">
<h3 id="hash"><a class="anchor" href="record-path-guide.html#hash"></a>hash</h3>
<div class="paragraph">
<p>Converts a String using a hash algorithm. For example, given a schema such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"type": "record",
"name": "events",
"fields": [
{ "name": "name", "type": "string" }
]
}</pre>
</div>
</div>
<div class="paragraph">
<p>and a record such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"name" : "John"
}</pre>
</div>
</div>
<div class="paragraph">
<p>The following record path expression would hash the String using one of these, [SHA-384, SHA-224, SHA-256, MD2, SHA, SHA-512, MD5] algorithms.</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>hash(/name, 'MD5')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">527bd5b5d689e2c32ae974c6229ff785</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="padleft"><a class="anchor" href="record-path-guide.html#padleft"></a>padLeft</h3>
<div class="paragraph">
<p>Prepends characters to the input String until it reaches the desired length.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"type": "record",
"name": "events",
"fields": [
{ "name": "name", "type": "string" }
]
}</pre>
</div>
</div>
<div class="paragraph">
<p>and a record such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"name" : "john smith"
}</pre>
</div>
</div>
<div class="paragraph">
<p>The following record path expression would prepend '@' characters to the input String:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>padLeft(/name, 15, '@')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">@@@@@john smith</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="padright"><a class="anchor" href="record-path-guide.html#padright"></a>padRight</h3>
<div class="paragraph">
<p>Appends characters to the input String until it reaches the desired length.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"type": "record",
"name": "events",
"fields": [
{ "name": "name", "type": "string" }
]
}</pre>
</div>
</div>
<div class="paragraph">
<p>and a record such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"name" : "john smith"
}</pre>
</div>
</div>
<div class="paragraph">
<p>The following record path expression would append '@' characters to the input String:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>padRight(/name, 15, '@')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">john smith@@@@@</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="uuid5"><a class="anchor" href="record-path-guide.html#uuid5"></a>uuid5</h3>
<div class="paragraph">
<p>Inserts a UUID v5 into the target field.</p>
</div>
<div class="paragraph">
<p>There are two ways to use this function: with or without a namespace. Given this schema:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"type": "record",
"name": "events",
"fields": [
{ "name": "input", "type": "string" },
{ "name": "id_ns", "type": "string" }
]
}</pre>
</div>
</div>
<div class="paragraph">
<p>and a record such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
"input" : "john smith",
"id_ns": "02b317d3-7fec-421a-89c5-3ad0eb83c79e"
}</pre>
</div>
</div>
<div class="paragraph">
<p>There are two options for using this function:</p>
</div>
<div class="paragraph">
<p><code>uuid5(/input)</code></p>
</div>
<div class="paragraph">
<p><code>uuid5(/input, /id_ns)</code></p>
</div>
<div class="paragraph">
<p>The first option will generate a simple UUID v5 that does not use a namespace in the generation process. The second will
take the value of the supplied record path and use it as the namespace.</p>
</div>
<div class="paragraph">
<p>Please note that the namespace must always be a valid UUID string. An empty string, another data type, etc. will result
in an error. This is by design because the most common use case for UUID v5 is to uniquely identify records across data sets.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="filter_functions"><a class="anchor" href="record-path-guide.html#filter_functions"></a>Filter Functions</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="contains"><a class="anchor" href="record-path-guide.html#contains"></a>contains</h3>
<div class="paragraph">
<p>Returns <code>true</code> if a String value contains the provided substring, <code>false</code> otherwise</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/name[contains(., 'o')]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/name[contains(., 'x')]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;returns no results&gt;</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/name[contains( ../workAddress/state, /details/preferredState )]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="matchesregex"><a class="anchor" href="record-path-guide.html#matchesregex"></a>matchesRegex</h3>
<div class="paragraph">
<p>Evaluates a Regular Expression against the contents of a String value and returns <code>true</code> if the Regular Expression
exactly matches the String value, <code>false</code> otherwise.
This function requires 2 arguments: the String to run the regular expression against, and the regular expression to run.</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/name[matchesRegex(., 'John Doe')]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/name[matchesRegex(., 'John')]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;returns no results&gt;</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/name[matchesRegex(., '.* Doe' )]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="startswith"><a class="anchor" href="record-path-guide.html#startswith"></a>startsWith</h3>
<div class="paragraph">
<p>Returns <code>true</code> if a String value starts with the provided substring, <code>false</code> otherwise</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/name[startsWith(., 'J')]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/name[startsWith(., 'x')]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;returns no results&gt;</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/name[startsWith(., 'xyz')]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;returns no results&gt;</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/name[startsWith(., '')]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="endswith"><a class="anchor" href="record-path-guide.html#endswith"></a>endsWith</h3>
<div class="paragraph">
<p>Returns <code>true</code> if a String value ends with the provided substring, <code>false</code> otherwise</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/name[endsWith(., 'e')]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/name[endsWith(., 'x')]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;returns no results&gt;</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/name[endsWith(., 'xyz')]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;returns no results&gt;</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/name[endsWith(., '')]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="not"><a class="anchor" href="record-path-guide.html#not"></a>not</h3>
<div class="paragraph">
<p>Inverts the value of the function or expression that is passed into the <code>not</code> function.</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/name[not(endsWith(., 'x'))]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/name[not(contains(., 'x'))]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/name[not(endsWith(., 'e'))]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;returns no results&gt;</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="isempty"><a class="anchor" href="record-path-guide.html#isempty"></a>isEmpty</h3>
<div class="paragraph">
<p>Returns <code>true</code> if the provided value is either null or is an empty string.</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/name[isEmpty(/details/employer)]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/name[isEmpty(/details/vehicle)]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/name[isEmpty(/details/phase)]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;returns no results&gt;</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/name[isEmpty(.)]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;returns no results&gt;</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="isblank"><a class="anchor" href="record-path-guide.html#isblank"></a>isBlank</h3>
<div class="paragraph">
<p>Returns <code>true</code> if the provided value is either null or is an empty string or a string that consists
only of white space (spaces, tabs, carriage returns, and new-line characters).</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RecordPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Return value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/name[isBlank(/details/employer)]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/name[isBlank(/details/vehicle)]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/name[isBlank(/details/phase)]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">John Doe</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/name[isBlank(.)]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;returns no results&gt;</p></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2022-12-05 18:19:00 -0600
</div>
</div>
</body>
</html>