Skip to content

Commit fc1d292

Browse files
authored
custom_func reference (#132)
1 parent 3cd7588 commit fc1d292

File tree

1 file changed

+300
-0
lines changed

1 file changed

+300
-0
lines changed

doc/customfuncs.md

Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,301 @@
11
# Custom Function Reference
2+
3+
## Global `custom_func` Available to All Extensions and Versions of Schema Handlers
4+
5+
> ### coalesce
6+
7+
**Synopsis**: `coalesce` returns the first non-empty string of the input strings. If no input
8+
strings are given or all of them are empty, then empty string is returned. Note: a blank
9+
string (with only whitespaces) is not considered as empty.
10+
11+
**Pkg doc**: [here](https://pkg.go.dev/github.com/jf-tech/omniparser/customfuncs#Coalesce).
12+
13+
**Example**:
14+
```
15+
"tracking_number": { "custom_func": {
16+
"name": "coalesce",
17+
"args": [
18+
{ "xpath": "tracking_number_h002_cn" },
19+
{ "xpath": "tracking_number_h001" }
20+
]
21+
}}
22+
```
23+
If IDR node `tracking_number_h002_cn` value is `""` and `tracking_number_h001` value is `"ABC"`,
24+
then the result field `tracking_number` value is `"ABC"`.
25+
---
26+
27+
> ### concat
28+
29+
**Synopsis**: `concat` concatenates a number of strings together. If no strings specified, `""` is
30+
returned.
31+
32+
**Pkg doc**: [here](https://pkg.go.dev/github.com/jf-tech/omniparser/customfuncs#Concat).
33+
34+
**Example**:
35+
```
36+
"event_date_time": { "custom_func": {
37+
"name": "concat",
38+
"args": [
39+
{ "xpath": "event_date" },
40+
{ "const": "T" },
41+
{ "xpath": "event_time" }
42+
]
43+
}}
44+
```
45+
If IDR node `event_date` value is `"12/31/2020"` and `event_time` value is `"12:34:56"`,
46+
then the result field `event_date_time` value is `"12/31/2020T12:34:56"`.
47+
---
48+
49+
> ### dateTimeLayoutToRFC3339
50+
51+
**Synopsis**: `dateTimeLayoutToRFC3339` parses a datetime string according to a given layout, and
52+
normalizes and returns it in RFC3339 format.
53+
54+
**Pkg doc**: [here](https://pkg.go.dev/github.com/jf-tech/omniparser/customfuncs#DateTimeLayoutToRFC3339).
55+
56+
**Example**:
57+
```
58+
"day_before_month": { "custom_func": {
59+
"name": "dateTimeLayoutToRFC3339",
60+
"args": [
61+
{ "xpath": "DayBeforeMonth" },
62+
{ "const": "02/01/06T15:04:05", "_comment": "layout" },
63+
{ "const": "false", "_comment": "layoutTZ" },
64+
{ "const": "Pacific/Auckland", "_comment": "fromTZ" },
65+
{ "const": "America/Los_Angeles", "_comment": "toTZ" }
66+
]
67+
}}
68+
```
69+
If IDR node `DayBeforeMonth` value is `"31/12/20T12:34:56"`, then the result field
70+
`day_before_month` value is `"2020-12-30T15:34:56-08:00"`: first, input `"31/12/20T12:34:56"`
71+
is parsed in the time zone of `"Pacific/Auckland"` which is GMT+13 at that moment of time.
72+
So the input datetime string, if translated into UTC, is `"2020-12-30T23:34:56Z"`. Now the caller
73+
specifies the desired output timezone to be `"America/Los_Angeles"` which is GMT-8 at that moment
74+
of time, so the eventual output is `"2020-12-30T15:34:56-08:00"`.
75+
76+
Param `layoutTZ` should be a boolean string value `"true"` or `"false"`, depending on if the
77+
provided `layout` param contains TZ info (such as `Z` suffix, or tz offset like `-08:00`) in it or
78+
not. If `layout` has TZ info, then `fromTZ` param will be ignored; if `layout` and input don't have
79+
TZ info, and `fromTZ` is specified, then the datetime string will be parsed in as if it's in the
80+
`fromTZ` timezone. If `toTZ` is empty, then whatever the tz from the input parsing will remain intact;
81+
or the parsed input datetime will be converted into the `toTZ`.
82+
83+
If you're not sure, please check
84+
[this sample](../extensions/omniv21/samples/xml/1_datetime_parse_and_format.schema.json) to find out
85+
more subtleties about date time parsing and conversion.
86+
---
87+
88+
> ### dateTimeToEpoch
89+
90+
**Synopsis**: `dateTimeToEpoch` parses a datetime string intelligently, and returns its epoch number.
91+
92+
**Pkg doc**: [here](https://pkg.go.dev/github.com/jf-tech/omniparser/customfuncs#DateTimeToEpoch).
93+
94+
**Example**:
95+
```
96+
"epoch": { "custom_func": {
97+
"name": "dateTimeToEpoch",
98+
"args": [
99+
{ "xpath": "event_datetime" },
100+
{ "const": "", "_comment": "fromTZ" },
101+
{ "const": "SECOND", "_comment": "unit" }
102+
]
103+
}}
104+
```
105+
If IDR node `event_datetime` value is `"12/31/2020T12:34:56Z"`, then the result field
106+
`epoch` value is `"1609418096"`: first, input `"12/31/2020T12:34:56Z"`
107+
will be parsed in as is (since it has `Z` suffix, so it is time-zoned, plus `fromTZ` is `""`).
108+
Then the function converts the input datetime to epoch seconds.
109+
110+
Param `unit` has two valid values: `"SECOND"` or `"MILLISECOND"`.
111+
112+
---
113+
114+
> ### dateTimeToRFC3339
115+
116+
**Synopsis**: `dateTimeToRFC3339` parses a datetime string intelligently, normalizes and returns it
117+
in RFC3339 format.
118+
119+
**Pkg doc**: [here](https://pkg.go.dev/github.com/jf-tech/omniparser/customfuncs#DateTimeToRFC3339).
120+
121+
**Example**:
122+
```
123+
"no_tz_date_time_use_to_tz": { "custom_func": {
124+
"name": "dateTimeToRFC3339",
125+
"args": [
126+
{ "xpath": "DateTimeWithNoTZ" },
127+
{ "const": "", "_comment": "fromTZ" },
128+
{ "const": "America/Los_Angeles", "_comment": "toTZ" }
129+
]
130+
}},
131+
```
132+
This `custom_func` params and behavior is very similar to
133+
[`dateTimeLayoutToRFC3339`](#datetimelayouttorfc3339) except that it doesn't need a `layout` and it
134+
instead tries to parse the input datetime string intelligently.
135+
136+
If you're not sure, please check
137+
[this sample](../extensions/omniv21/samples/xml/1_datetime_parse_and_format.schema.json) to find out
138+
more subtleties about date time parsing and conversion.
139+
---
140+
141+
> ### epochToDateTimeRFC3339
142+
143+
**Synopsis**: `epochToDateTimeRFC3339` translates an epoch timestamp into an RFC3339 formatted datetime
144+
string.
145+
146+
**Pkg doc**: [here](https://pkg.go.dev/github.com/jf-tech/omniparser/customfuncs#EpochToDateTimeRFC3339).
147+
148+
**Example**:
149+
```
150+
"epoch_to_datetime": { "custom_func": {
151+
"name": "epochToDateTimeRFC3339",
152+
"args": [
153+
{ "xpath": "event_epoch" },
154+
{ "const": "MILLISECOND", "_comment": "unit" }
155+
]
156+
}}
157+
```
158+
If IDR node `event_epoch` value is `"1609418096000"`, then the result field
159+
`epoch_to_datetime` value is `"2020-12-31T12:34:56Z"`: first, input `"1609418096000"`
160+
will be parsed in as epoch value in milliseconds. Then the function converts the epoch value
161+
to RFC3339 string.
162+
163+
Param `unit` has two valid values: `"SECOND"` or `"MILLISECOND"`.
164+
165+
There is an optional param at the end, `tz`: if not specified, the output will be in UTC (`Z`)
166+
time zone; if specified, it must be of a standard IANA time zone string, such as
167+
`"America/Los_Angeles"`.
168+
---
169+
170+
> ### lower
171+
172+
**Synopsis**: `lower` lowers the case of an input string.
173+
174+
**Pkg doc**: [here](https://pkg.go.dev/github.com/jf-tech/omniparser/customfuncs#Lower).
175+
176+
**Example**:
177+
```
178+
"carrier": { "custom_func": { "name": "lower", "args": [ { "xpath": "../GLOBAL/carrier" } ] } },
179+
```
180+
If IDR node `../GLOBAL/carrier` value is `"ABC"`, then the result field `carrier` value is `"abc"`.
181+
182+
---
183+
184+
> ### now
185+
186+
**Synopsis**: `now` returns the current time in UTC in RFC3339 format.
187+
188+
**Pkg doc**: [here](https://pkg.go.dev/github.com/jf-tech/omniparser/customfuncs#Now).
189+
190+
**Example**:
191+
```
192+
"now_datetime": { "custom_func": { "name": "now" }},
193+
```
194+
The result field `now_datetime` value will be the current system datetime in UTC in RFC3339.
195+
196+
---
197+
198+
> ### upper
199+
>
200+
**Synopsis**: `upper` uppers the case of an input string.
201+
202+
**Pkg doc**: [here](https://pkg.go.dev/github.com/jf-tech/omniparser/customfuncs#Upper).
203+
204+
**Example**:
205+
```
206+
"carrier": { "custom_func": { "name": "upper", "args": [ { "xpath": "../GLOBAL/carrier" } ] } },
207+
```
208+
If IDR node `../GLOBAL/carrier` value is `"abc"`, then the result field `carrier` value is `"ABC"`.
209+
210+
---
211+
212+
> ### uuidv3
213+
214+
**Synopsis**: `uuidv3` uses MD5 to produce a consistent/stable UUID for an input string.
215+
216+
**Pkg doc**: [here](https://pkg.go.dev/github.com/jf-tech/omniparser/customfuncs#UUIDv3).
217+
218+
**Example**:
219+
```
220+
"unique_customer_order_id": { "custom_func": {
221+
"name": "uuidv3",
222+
"args": [
223+
{ "custom_func": {
224+
"name": "concat",
225+
"args: [
226+
{ "xpath": "customer_id" },
227+
{ "const": "/" },
228+
{ "xpath": "order_id" }
229+
]
230+
}}
231+
]
232+
}}
233+
```
234+
The result field `unique_customer_order_id` will contain the value of an MD5 hash of the concatenated
235+
string of customer_id value, `"/"`, and order_id value.
236+
237+
---
238+
239+
## `omni.2.1` Schema Handler Specific `custom_func`
240+
241+
> ### copy
242+
243+
**Synopsis**: `copy` copies the current contextual `idr.Node` and returns it as a JSON marshaling
244+
friendly `interface{}`.
245+
246+
**Pkg doc**: [here](https://pkg.go.dev/github.com/jf-tech/omniparser/extensions/omniv21/customfuncs#CopyFunc).
247+
248+
**Example**:
249+
```
250+
"first_book": { "xpath": "book[position() = 1]", "custom_func": { "name": "copy"} },
251+
```
252+
The result field `first_book` will be an exact copy of first `book` node from the input.
253+
254+
---
255+
256+
> ### javascript
257+
258+
**Synopsis**: `javascript` runs a javascript.
259+
260+
**Pkg doc**: [here](https://pkg.go.dev/github.com/jf-tech/omniparser/extensions/omniv21/customfuncs#JavaScript).
261+
262+
**Example**:
263+
```
264+
"avg_price": {
265+
"custom_func": {
266+
"name": "javascript",
267+
"args": [
268+
{ "const": "t=0; for(i=0; i<prices.length; i++) { t+=prices[i]; } Math.floor(t*100/prices.length)/100;" },
269+
{ "const": "prices" }, { "array": [ { "xpath": "books/*/price", "type": "float" } ] }
270+
]
271+
}
272+
},
273+
```
274+
The result field `avg_price` will contain the average price (to the 2nd decimal places) of all the
275+
book prices.
276+
277+
For more information about `javascript`, check this
278+
[in-depth explanation](./use_of_custom_funcs.md#javascript-and-javascript_with_context).
279+
---
280+
281+
> ### javascript_with_context
282+
283+
**Synopsis**: `javascript_with_context` runs a javascript with contextual `_node` provided.
284+
285+
**Pkg doc**: [here](https://pkg.go.dev/github.com/jf-tech/omniparser/extensions/omniv21/customfuncs#JavaScriptWithContext).
286+
287+
**Example**:
288+
```
289+
"full_name": { "xpath": "./personal_info", "custom_func" {
290+
"name": "javascript_with_context",
291+
"args": [
292+
{ "const": "var n = JSON.parse(_node); n.['Last Name'] + ', ' + n.['First Name']" }
293+
]
294+
}}
295+
```
296+
The result field `full_name` will be a concatenated string of the last name and the first name from
297+
the current IDR node.
298+
299+
For more information about `javascript_with_context`, check this
300+
[in-depth explanation](./use_of_custom_funcs.md#javascript-and-javascript_with_context).
301+
---

0 commit comments

Comments
 (0)