KRL supports integer and real values. A negative number is created by prepending the minus sign (-) to a number.
Strings
String are created by enclosing characters in double quote characters (").
Arrays
Arrays are created by enclosing comma-delimited expressions in square brackets like so:
["a", "b", "c"]
Arrays can be referenced in the usual manner:
a = [1,4,3,6,5];
b = a[1]
This would bind the value 4 to the variable b. Note that array references only work for arrays of one-dimension, so c[1][2] is not allowed (presuming c is an array of arrays).
Hashes
Hashes are creating by enclosing comma-delimted name-value pairs in curly braces like so:
{"foo" : "bar", "fizz" : 3, "flop" : [1, 2, 3]}
Extended Quoting
Some KRL statements and expressions make use of extended quotes which begin with << and end the >> For example:
pre {
somevar = <<
<p>This is <em>some</em> HTML.<br/>
<a href="http://www.google.com">Search Google</a>
</p>
>>;
}
Extended quotes allow multiple line passages that contain the " symbol to be entered as variables. Values inside the extended quotes are treated as strings.
Inside the string, variables can be referenced using the #{<varname>} syntax for simple templating. These variables are interpreted in the browser, not on the server.
Regular Expressions
Regular expressions are delimited by the slash character ("/") and most closely follow the conventions for Perl regular expressions. The following modifiers may appear after the trailing slash:
i - make the regular expression case insensitive
g - apply the regular expression globally
For example:
p.replace(/foo/,"bar")
would replace the first instance of "foo" in p with "bar".
p.replace(/foo/i, "bar")
would replace all instances of "foo" in p with "bar".
Simple Predicates
Several built-in operators allow testing for equality and inequality.
For numbers: <, >, <=, >=, ==, and !=
For strings: eq, neq, and like.
like takes a regular expression as its second argument and returns true if it matches the string given as it's first argument.
Predicate expressions are created by joining simple predicates with conjunction (&&) and disjunction (||) in rules. The not operator can also be applied to negate the value of a predicate expression.
The following predicates are built into KRL. If you think of others we ought to have, just ask.
The predicates are grouped by data source. All predicates must be namespaced using the datasource name and a colon. Not all datasources have predicates.
KRL supports the standard arithmetic operators: +, -, *, and / using infix notation. Parentheses are used to group expressions when normal precedence rules are to be overridden:
pre {
x = y + x;
a = a * (b + c);
p = q / 4;
}
String Expressions
KRL supports string concatenation using the + symbol:
pre {
x = "Hello " + "World!";
}
Conditional Expressions
KRL provides support for conditional expressions with the following syntax:
Because of the limitations of the recursive descent parser, most predicates will need to be enclosed in parentheses:
pre {
z = (x > y) => y | 3;
}
Functions
KRL supports functions as first-class objects in the expression language. KRL supports only anonymous functions, but they can be given names by binding them to a variable in a declaration. Here's an example:
pre {
add5 = function(x) {
x + 5
};
}
Functions are declared using the keyword function followed by a possibly-empty, parentheses-delimited, comma-seperated list of parameters and a block of code. The code block of the function is set off by curly braces and contains a list of semi-colon separated declarations and a single expression. The declarations are optional, but every function must have an expression as the last thing in the code block. The value of this expression is returned as the value of the function. Here is the BNF:
Functions are statically executed (e.g. the environment they are defined in, not the environment they are executed in determines the binding of free-variables) and can be recursive. The KNS execution environment limits the number of times a function can be called in any given ruleset evaluation to 1,000 to protect against run away code. Here's an example of a recursive function in KRL:
pre {
fact = function(n) {
(n <= 0) => 1
| n * fact(n-1)
}
}
The preceding example also shows the syntax for function application. An expression resulting in a function is followed by a possibly-empty, parentheses-delimited, comma-seperated list of expressions. Function application is applicative (e.g. the expressions representing the function and the arguments are evaluated and then the result of executing the function expression (the operator or rator) is applied to the results of evaluating the arguments (the operands or rands). Obviously, the rator must be a function.
Functions can return functions as values and functions can be passed as the arguments to other functions and operators in KRL. The following example defined a generalized summation function that sums the numbers from a to b incrementing using inc and applying the function f to each term:
sum = function(f, a, next, b) {
(a > b) => 0
| f(a) + sum(f, next(a), inc, b)
};
inc = function(x) { x + 1 };
cube = function(x) { x * x * x };
sum_cubes = function(a, b) {
sum(cube, a, inc, b)
}
We could define a function that creates incrementor functions. When given a number, it returns a function that increments by that value:
inc_generator = function(n) { function(x){ x + n } };
inc = inc_generator(1);
inc_by_2 = inc_generator(2);
inc_by_25 = inc_generator(25);
Note that function returns that create closures, like the ones above, may not execute correctly in the JavaScript environment, but they do execute correctly on the KNS server.
Data Sources
Datasource declarations take the following form:
<var> = <source>:<function>(<args>);
There are two kinds of data sources: intrinsic and user-defined.
Intrinsic Datasources
The following describes data sources available in KRL.
As described in the documentation for the global declarations, users can define data sources. They are queried in the pre declarations to produce a complex data structure. For example, if a data source named library_search had been declared, it could be queried like so:
pre {
book_data = datasource:library_search("q="+isbn);
}
The datasource takes a single parameter of either a string or a hash.
If the parameter is a string, then it is concatenated with the URL root given in the datasource declaration without modification. What you supply here, when appended to the datasource root URL must result in exactly the URL that you intend to call.
If the parameter is a hash, then the has is turned into a properly formatted HTTP QUERY string with names 7 values delimited by an equals sign (=) to create a name-value pair and each name-value pair delimited by an ampersand (&).
If you intend to use the results of the query in a Javascript expression to be executed on the server, note that the value of the right hand side is stored in KOBJ['data'][lhs] where lhs is the left hand side of the declaration. Note that because a ruleset might execute with any other ruleset, variable names should be chosen to avoid name clashes.
Complex data can be queried and used using the pick operator.
Persistent Variables
Note: only entity persistents are currently supported by the production KNS system.
There are two types of persistent variables:
Entity variables are used to record persisten data about individuals interacting with rules. Entity variables are identified by the domain ent.
Application variables are used to record persistent data about the application or ruleset. Application variables are identified by the domain app.
Persistent variables take three forms:
flags
counters
trails
Flags store boolean values. Counters store (and, obviously count and test) numeric values. Trails keep track of page visits and other state information. Trails are limited storing 20 places.
As an example, the following rule uses a counter to fire an action when an individual has visited a collection of web pages (anything in the archive directory) more than twice in the last three days:
rule frequent_archive_visitor is active {
select using "/archives/\d+/\d+/" setting ()
pre {
c = ent:archive_pages;
}
if ent:archive_pages > 2 within 3 days then {
alert("You win the prize! You've seen " + c + " pages from the archives!")
}
fired {
clear ent:archive_pages;
} else {
ent:archive_pages += 1 from 1;
}
}
The following rule will create a counter of all the visitors to the archive pages and replace an page element with an id of page_count with the current count:
rule count_archive_visitors is active {
select using "/archives/\d+/\d+/" setting ()
pre {
c = app:visitor_count;
res = <<
<div id="page_count">#{c}</div>
>>
}
replace("#page_count", res)
fired {
app:visitor_count += 1 from 1;
}
}
Persistent variables can be used in expressions as part of a prelude section in a rule, in predicates as part of a conditional action, and in mutator statements as part of a postlude or callback.
Using Persistents in Preludes
Flags and counters can be used inside prelude expressions like any other variable. You cannot use them inside extended quotations as template variables. If the persistent variable does not exist before it is used, the default value is 0. Note that variable references for uninitialized persistent variables are not typed and so it is treated as a counter.
The following example shows the use of a persistent variable in a prelude statement:
pre {
c = ent:archive_pages;
d = <<
This is a page that has been accessed #{c} times
>>
}
Persistent trails have special operators for accessing individual places in the trail.
The history function takes an expression and a persistent variable. If the expression evaluates to n then the history function will return the n_th place on the trail. The most recent place is at history location 0.
The current function takes a persistent variable. The current function performs the same operation as the history function with a location of 0. That is, it returns the most recent place on the trail.
Using Persistents in Predicates
For most uses in predicates, persistents are accessed in the same way as in the prelude. So, the following action will fire when the persisent variable ent:archive_pages is greater than 3:
if ent:archive_pages > 3 then
notify(...)
Persistent flags and counters can also be tested with an associated timeframe. For example, the following action will fire when persisent variable ent:archive_pages is greater than 3 and the last time it as set was within the last 2 hours:
if ent:archive_pages > 3 within 2 hours then
notify(...)
where PVAR is a persistent flag or counter and EXPR is any valid KRL expression.
Persistent trails can be tested using the seen predicate. There are two forms.
The first form asks whether a regular expression has been seen within an optional timeframe (specified exactly as above). So you can say:
if seen "/archive/2006" in ent:my_trail then
notify(...)
or
if seen "/archive/2006" in ent:my_trail within 3 days then
notify(...)
The first arguments is a string that is interpreted as a regular expression.
The second form tests whether a place in a trail matching the first regular expression comes before or after a place in the same trail matching a second regular expression. This example
if seen "/archive/2006" before "/archive/2007" in ent:my_trail then
notify(...)
would fire the action when a place matching the regular expression "/archive/2006" was placed on the trail before a place matching the regular expression "/archive/2007".
Mutating Persistents
Persistent variables, to be useful, must be mutated, or changed permanently. The following statements mutate persistent varible:
clear PVAR - clears (sets to nil) the persistent variable PVAR
set PVAR - set (sets to true) the persistent variable PVAR making it a flag.
PVAR (+=|-=) EXPR from EXPR - increments (or decrements) the persistent variable PVAR by the value given by the first expression. If the value is null when the statement executes, the value of the second expression is used to initialize the persistent.
mark PVAR - mark the trail using the current caller URL as the place.
mark PVAR with EXPR - mark the trail using the value of the expression as the place.
forget STRING in PVAR - forget the place in the trail marked by the string when interpreted as a regular expression.
The package name is math. The following functions are available:
random(<num>) - generate a random number. The value is between 0 and the number given as an argument.
pre {
r = math:random(999)
}
would generate a random number between 0 and 999 and bind it to r.
Page IDs
You can use the contents of elements on the page with a specific CSS ID using the page ID delclaration. For example, the following comment will make the contents of the element with the ID itemnum available as the variable item_no.
item_no = page:id("itemnum")
Note that page IDs cannot be used in predicates since the values are not available on the server, but only on the client. They can be used in declarations and as arguments to actions.
Operators
Operators can be applied to expressions. The syntax puts the operator following a period after the expression in a post-fix notation like so
store.pick("$..book[0,1]")
For now, the only way to chain operators is to fully parenthesize the expression like so:
(store.pick("$..book[0,1]")).length()
instead of
store.pick("$..book[0,1]").length()
as
Coerce objects of one type to be an object of another. For example, the following constructs a string and then turns it into a regular expression that can be used by the replace operator.
("/q=" + q + "/i").as("regexp")
The following coercions are allowed:
str
num
regexp
array
hash
str
*
*
*
num
*
*
regexp
*
*
array
*
hash
*
Unsupported coercions will produce a warning and return the element with it's type unchanged.
length
Return the length of an array.
pick
The pick operator is used to pick out portions of a JSON data structure. Pick can be applied to any valid expression that returns JSON. Complex expressions should be contained in parentheses.
The pick operator takes a single string as an argument that represents a JSONPath expression that will select some portion of the JSON in the target expression (before the period).
For example, suppose that book_data contains the following JSON:
JSONPath always returns a "collection" or array. That is less than helpful in many circumstances inside KRL, so the pick operator will reduce single element arrays to just the singleton member.
Note: if you're trying to match data with a period (.) in the name, the period will be interpreted as a JSONPath operator unless you escape it with a backslash like so:
bar.pick("$..www\.kynetx\.com[0].text")
replace
The replace operator replaces the portion of a string matching a regular expression with another string.
str_expr.replace(/regexp/, "str")
The target (before the period) must be a string.
The first argument must be a regular expression. The i and g operators (for case insensativity and global replacement respectively) are supported.
The second argument is a string to use for replacement. The $n syntax for replacement of captured text from the regular expression is supported.
The following examples show how replace can be used. Suppose that my_str contains the string "This is a string" and my_url contains the string 'http://www.amazon.com/gp/products/123456789/':
my_str.replace(/is/,"ese") // returns 'These is a string'
my_str.replace(/is/g,"ese") // returns 'These ese a string'
my_str.replace(/this/,"do you want a") // returns 'This is a string' (no change)
my_str.replace(/this/i,"do you want a") // returns 'do you want a is a string'
my_str.replace(/Th(is)/,"Nothing $1") // returns 'Nothing is is a string'
my_url.replace(/http:\/\/([A-Za-z0-9.-]+)\/.*/,"$1") // returns 'www.amazon.com'
Note that this does not mutate the original string, but rather returns a new string that is built by making the substitution in the original.
Expressions
Literals
The following literals can be used within KRL.
Booleans
The boolean values are
trueandfalseNumbers
KRL supports integer and real values. A negative number is created by prepending the minus sign (
-) to a number.Strings
String are created by enclosing characters in double quote characters (
").Arrays
Arrays are created by enclosing comma-delimited expressions in square brackets like so:
Arrays can be referenced in the usual manner:
This would bind the value 4 to the variable
b. Note that array references only work for arrays of one-dimension, soc[1][2]is not allowed (presumingcis an array of arrays).Hashes
Hashes are creating by enclosing comma-delimted name-value pairs in curly braces like so:
{"foo" : "bar", "fizz" : 3, "flop" : [1, 2, 3]}Extended Quoting
Some KRL statements and expressions make use of extended quotes which begin with
<<and end the>>For example:pre { somevar = << <p>This is <em>some</em> HTML.<br/> <a href="http://www.google.com">Search Google</a> </p> >>; }Extended quotes allow multiple line passages that contain the " symbol to be entered as variables. Values inside the extended quotes are treated as strings.
Inside the string, variables can be referenced using the #{<varname>} syntax for simple templating. These variables are interpreted in the browser, not on the server.
Regular Expressions
Regular expressions are delimited by the slash character ("/") and most closely follow the conventions for Perl regular expressions. The following modifiers may appear after the trailing slash:
For example:
would replace the first instance of "foo" in p with "bar".
would replace all instances of "foo" in p with "bar".
Simple Predicates
Several built-in operators allow testing for equality and inequality.
For numbers: <, >, <=, >=, ==, and !=
For strings: eq, neq, and like.
like takes a regular expression as its second argument and returns true if it matches the string given as it's first argument.
Arguments can be any valid expression.
The following are all valid tests for equality:
c == 5 page:var("city") eq "Blackfoot" "Orem" neq location:city() weather:curr_temp() < 90 location:city() + ", WA" eq city 5 * (weather:curr_temp() - 32) / 9 < 0Predicate Expressions
Predicate expressions are created by joining simple predicates with conjunction (&&) and disjunction (||) in rules. The
notoperator can also be applied to negate the value of a predicate expression.The following are examples of valid predicates:
Intrinsic Predicates
The following predicates are built into KRL. If you think of others we ought to have, just ask.
The predicates are grouped by data source. All predicates must be namespaced using the datasource name and a colon. Not all datasources have predicates.
Demographic Predicates
The data used by this data source is from the 2000 US Census. Demographic data is only available for US households at present.
Weather Predicates
All predicates are relative to local weather. That is weather where the user is.
Time Predicates
All of the following predicates are referenced to the user's local time. All times are 24-hour clock.
Economic Indicator Predicates
These are experimental and mostly for demonstration purposes.
Referer Predicates
Location Predicates
Arithmetic Expressions
KRL supports the standard arithmetic operators: +, -, *, and / using infix notation. Parentheses are used to group expressions when normal precedence rules are to be overridden:
pre { x = y + x; a = a * (b + c); p = q / 4; }String Expressions
KRL supports string concatenation using the + symbol:
pre { x = "Hello " + "World!"; }Conditional Expressions
KRL provides support for conditional expressions with the following syntax:
These can be nested to produce:
<pred0> => <expr0> | <pred1> => <expr1> | <pred2> => <expr2> | ... | <exprn>Because of the limitations of the recursive descent parser, most predicates will need to be enclosed in parentheses:
pre { z = (x > y) => y | 3; }Functions
KRL supports functions as first-class objects in the expression language. KRL supports only anonymous functions, but they can be given names by binding them to a variable in a declaration. Here's an example:
pre { add5 = function(x) { x + 5 }; }Functions are declared using the keyword
functionfollowed by a possibly-empty, parentheses-delimited, comma-seperated list of parameters and a block of code. The code block of the function is set off by curly braces and contains a list of semi-colon separated declarations and a single expression. The declarations are optional, but every function must have an expression as the last thing in the code block. The value of this expression is returned as the value of the function. Here is the BNF:function_def: 'function' '(' VAR(s? /,/) ')' '{' fundecls(?) expr '}' fundecls: decl(s? /;/) ';'Functions are statically executed (e.g. the environment they are defined in, not the environment they are executed in determines the binding of free-variables) and can be recursive. The KNS execution environment limits the number of times a function can be called in any given ruleset evaluation to 1,000 to protect against run away code. Here's an example of a recursive function in KRL:
pre { fact = function(n) { (n <= 0) => 1 | n * fact(n-1) } }The preceding example also shows the syntax for function application. An expression resulting in a function is followed by a possibly-empty, parentheses-delimited, comma-seperated list of expressions. Function application is applicative (e.g. the expressions representing the function and the arguments are evaluated and then the result of executing the function expression (the operator or rator) is applied to the results of evaluating the arguments (the operands or rands). Obviously, the rator must be a function.
Consider the following example which uses Newton's method to calculate square roots (taken from Section 1.1.8 of Structure and Interpretation of Computer Programs):
sqrt = function(x) { average = function(x,y) { (x + y) / 2 }; good_enough = function(guess, x) { v = (guess * guess) - x; v < 0.01 && v > -0.01 }; improve = function(guess, x) { average(guess, (x / guess)) } sqrt_iter = function(guess, x) { good_enough(guess, x) => guess | sqrt_iter(improve(guess,x), x) }; sqrt_iter(1.0, x) }Functions can return functions as values and functions can be passed as the arguments to other functions and operators in KRL. The following example defined a generalized summation function that sums the numbers from
atobincrementing usingincand applying the functionfto each term:sum = function(f, a, next, b) { (a > b) => 0 | f(a) + sum(f, next(a), inc, b) }; inc = function(x) { x + 1 }; cube = function(x) { x * x * x }; sum_cubes = function(a, b) { sum(cube, a, inc, b) }We could define a function that creates incrementor functions. When given a number, it returns a function that increments by that value:
inc_generator = function(n) { function(x){ x + n } }; inc = inc_generator(1); inc_by_2 = inc_generator(2); inc_by_25 = inc_generator(25);Note that function returns that create closures, like the ones above, may not execute correctly in the JavaScript environment, but they do execute correctly on the KNS server.
Data Sources
Datasource declarations take the following form:
There are two kinds of data sources: intrinsic and user-defined.
Intrinsic Datasources
The following describes data sources available in KRL.
Weather
The <source> for weather is weather.
Location
The <source> for location is location.
Referer
The <source> for referer is referer.
Media Market
The <source> for media market is mediamarket.
Stocks
The <source> for stock is stocks.
Page
The <source> for page data sources is page.
User Agent
The <source> for page data sources is useragent.
User Defined Data Sources
As described in the documentation for the global declarations, users can define data sources. They are queried in the
predeclarations to produce a complex data structure. For example, if a data source named library_search had been declared, it could be queried like so:pre { book_data = datasource:library_search("q="+isbn); }The datasource takes a single parameter of either a string or a hash.
If you intend to use the results of the query in a Javascript expression to be executed on the server, note that the value of the right hand side is stored in KOBJ['data'][lhs] where lhs is the left hand side of the declaration. Note that because a ruleset might execute with any other ruleset, variable names should be chosen to avoid name clashes.
Complex data can be queried and used using the pick operator.
Persistent Variables
Note: only entity persistents are currently supported by the production KNS system.
There are two types of persistent variables:
ent.app.Persistent variables take three forms:
Flags store boolean values. Counters store (and, obviously count and test) numeric values. Trails keep track of page visits and other state information. Trails are limited storing 20 places.
As an example, the following rule uses a counter to fire an action when an individual has visited a collection of web pages (anything in the
archivedirectory) more than twice in the last three days:rule frequent_archive_visitor is active { select using "/archives/\d+/\d+/" setting () pre { c = ent:archive_pages; } if ent:archive_pages > 2 within 3 days then { alert("You win the prize! You've seen " + c + " pages from the archives!") } fired { clear ent:archive_pages; } else { ent:archive_pages += 1 from 1; } }The following rule will create a counter of all the visitors to the archive pages and replace an page element with an
idofpage_countwith the current count:rule count_archive_visitors is active { select using "/archives/\d+/\d+/" setting () pre { c = app:visitor_count; res = << <div id="page_count">#{c}</div> >> } replace("#page_count", res) fired { app:visitor_count += 1 from 1; } }Persistent variables can be used in expressions as part of a prelude section in a rule, in predicates as part of a conditional action, and in mutator statements as part of a postlude or callback.
Using Persistents in Preludes
Flags and counters can be used inside prelude expressions like any other variable. You cannot use them inside extended quotations as template variables. If the persistent variable does not exist before it is used, the default value is 0. Note that variable references for uninitialized persistent variables are not typed and so it is treated as a counter.
The following example shows the use of a persistent variable in a prelude statement:
pre { c = ent:archive_pages; d = << This is a page that has been accessed #{c} times >> }Persistent trails have special operators for accessing individual places in the trail.
historyfunction takes an expression and a persistent variable. If the expression evaluates tonthen thehistoryfunction will return the n_th place on the trail. The most recent place is at history location 0.currentfunction takes a persistent variable. Thecurrentfunction performs the same operation as thehistoryfunction with a location of 0. That is, it returns the most recent place on the trail.Using Persistents in Predicates
For most uses in predicates, persistents are accessed in the same way as in the prelude. So, the following action will fire when the persisent variable
ent:archive_pagesis greater than 3:Persistent flags and counters can also be tested with an associated timeframe. For example, the following action will fire when persisent variable
ent:archive_pagesis greater than 3 and the last time it as set was within the last 2 hours:The syntax of timeframe limited predicates is
where
PVARis a persistent flag or counter andEXPRis any valid KRL expression.Persistent trails can be tested using the
seenpredicate. There are two forms.The first form asks whether a regular expression has been
seenwithin an optional timeframe (specified exactly as above). So you can say:or
The first arguments is a string that is interpreted as a regular expression.
The second form tests whether a place in a trail matching the first regular expression comes before or after a place in the same trail matching a second regular expression. This example
would fire the action when a place matching the regular expression
"/archive/2006"was placed on the trail before a place matching the regular expression"/archive/2007".Mutating Persistents
Persistent variables, to be useful, must be mutated, or changed permanently. The following statements mutate persistent varible:
clear PVAR- clears (sets to nil) the persistent variablePVARset PVAR- set (sets to true) the persistent variablePVARmaking it a flag.PVAR (+=|-=) EXPR from EXPR- increments (or decrements) the persistent variablePVARby the value given by the first expression. If the value is null when the statement executes, the value of the second expression is used to initialize the persistent.mark PVAR- mark the trail using the current caller URL as the place.mark PVAR with EXPR- mark the trail using the value of the expression as the place.forget STRING in PVAR- forget the place in the trail marked by the string when interpreted as a regular expression.Persistent variable mutator statements can appear in postlude sections or callback sections of rules.
Built-In Packages and Functions
The syntax for using a built-in function is
Math
The package name is
math. The following functions are available:random(<num>)- generate a random number. The value is between 0 and the number given as an argument.pre { r = math:random(999) }would generate a random number between 0 and 999 and bind it to
r.Page IDs
You can use the contents of elements on the page with a specific CSS ID using the page ID delclaration. For example, the following comment will make the contents of the element with the ID itemnum available as the variable item_no.
item_no = page:id("itemnum")Note that page IDs cannot be used in predicates since the values are not available on the server, but only on the client. They can be used in declarations and as arguments to actions.
Operators
Operators can be applied to expressions. The syntax puts the operator following a period after the expression in a post-fix notation like so
store.pick("$..book[0,1]")For now, the only way to chain operators is to fully parenthesize the expression like so:
(store.pick("$..book[0,1]")).length()instead of
store.pick("$..book[0,1]").length()asCoerce objects of one type to be an object of another. For example, the following constructs a string and then turns it into a regular expression that can be used by the
replaceoperator.("/q=" + q + "/i").as("regexp")The following coercions are allowed:
Unsupported coercions will produce a warning and return the element with it's type unchanged.
lengthReturn the length of an array.
pickThe pick operator is used to pick out portions of a JSON data structure. Pick can be applied to any valid expression that returns JSON. Complex expressions should be contained in parentheses.
The pick operator takes a single string as an argument that represents a JSONPath expression that will select some portion of the JSON in the target expression (before the period).
For example, suppose that book_data contains the following JSON:
{"responseHeader":{ "status":0, "QTime":0, "params":{ "q":"0316160202", "wt":"json"}}, "response":{ "numFound":1, "start":0, "docs":[ {"isbn":"0316160202", "title":"Eclipse", "url":"http://library.minlib.net/search/i?SEARCH=0316160202"}]}}The following table shows some sample JSON picks on this data and the results
JSONPath always returns a "collection" or array. That is less than helpful in many circumstances inside KRL, so the pick operator will reduce single element arrays to just the singleton member.
Note: if you're trying to match data with a period (.) in the name, the period will be interpreted as a JSONPath operator unless you escape it with a backslash like so:
bar.pick("$..www\.kynetx\.com[0].text")replaceThe
replaceoperator replaces the portion of a string matching a regular expression with another string.iandgoperators (for case insensativity and global replacement respectively) are supported.$nsyntax for replacement of captured text from the regular expression is supported.The following examples show how replace can be used. Suppose that
my_strcontains the string"This is a string"andmy_urlcontains the string'http://www.amazon.com/gp/products/123456789/':Note that this does not mutate the original string, but rather returns a new string that is built by making the substitution in the original.