Parsing functions
TapHome script parsing functions — PARSETEXT for text between patterns, PARSEJSON with JSONPath and PARSEXML with XPath — for reading values from device responses.
Parsing functions read values from text that a device returns — typically the response of an HTTP request or a received message in a Packet parser script. They accept a string, a byte collection (collection<uint8>) or a blob, work in every script and need Core 2022.2 or newer.
PARSETEXT
PARSETEXT returns the part of a text that follows a left pattern and ends before a right pattern; when that part is a number, a number is returned.
| |
| Name | Type | Description |
|---|---|---|
source | string, collection<uint8> or blob | Text to search. Bytes are read as iso-8859-1. |
leftPattern | string | Text before the value. Several parts separated by ... are found one after another. |
rightPattern | string, optional | Text after the value. Without it the value ends at the first character that is not a letter, a digit or . (a leading + or - is kept). |
Returns — a number when the found text reads as a number (with a decimal point), otherwise the text with spaces trimmed. Null when the left pattern is not found.
When the left pattern is found but the right pattern is not, the script stops with the error Specified argument was out of the range of valid values. — it does not return
Null. When the right pattern may be missing, check it withINDEXOFfirst (verified on Core 2026.1, build 40599).
Example
PARSETEXT("Lorem ipsum dolor sit amet", "ipsum", "amet");
# Result: "dolor sit"
PARSETEXT("<temp>12.2</temp>", "<temp>", "</temp>");
# Result: 12.2
PARSETEXT("<temp>12.2</temp>", "<temp>");
# Result: 12.2
PARSETEXT("status:ok,error:none", "status:");
# Result: "ok"
PARSETEXT("Lorem ipsum dolor sit amet", "ipsum...sit");
# Result: "amet"
PARSETEXT("Lorem ipsum dolor sit amet consectetur adipiscing", "ipsum...sit", "adipiscing");
# Result: "amet consectetur"
PARSETEXT("a=1", "b=");
# Result: NullExample — right pattern that may be missing
VAR start := INDEXOF(text, "temp=");
IF start < 0 OR INDEXOF(COPY(text, start), ";") < 0
RETURN(NaN);
END
PARSETEXT(text, "temp=", ";");PARSEJSON
PARSEJSON reads a value from JSON with a JSONPath expression; with TRUE as the third argument it returns Null instead of stopping the script when the path is not found.
| |
| Name | Type | Description |
|---|---|---|
json | string, collection<uint8> or blob | JSON text. |
path | string | JSONPath. The leading $. is optional. |
ignoreError | bool, optional | TRUE (or 1): return Null when the path is not found, the JSON is invalid or json is Null. Default FALSE. |
Returns — the value at the path: a string, a number or a bool. Several matches are returned as a collection. An object or an array is returned as its JSON text, which can be parsed again.
| Path | Selects |
|---|---|
temperature, cloud.connected | A field, a nested field. |
$.devices[0].name | A field of the first array element. |
$.devices[-1:].deviceId | The last element of an array. |
$[?(@.period == 1)].price | Elements whose field matches a condition. |
Example — with json holding:
| |
PARSEJSON(json, "firstName");
# Result: "John"
PARSEJSON(json, "address.city");
# Result: "Nara"
PARSEJSON(json, "age");
# Result: 26
PARSEJSON(json, "address.country", TRUE);
# Result: NullPARSEJSON(json, "address.country") without the third argument stops the script with PARSEJSON - Element not found: ‘address.country’.
Example — loop over a JSON array
With TRUE, PARSEJSON returns Null after the last element, which ends the loop:
VAR i := 0;
VAR names := "";
VAR name := PARSEJSON(json, "$.devices[0].name", TRUE);
WHILE !ISNULL(name)
names := names + name + "\n";
i := i + 1;
name := PARSEJSON(json, "$.devices[" + TOSTRING(i) + "].name", TRUE);
LOOP
names;Errors — PARSEJSON - Element not found: ‘path’; PARSEJSON - parse error: … (invalid JSON); PARSEJSON - argument 1 is null.
PARSEXML
PARSEXML reads a value from XML with an XPath expression and returns the value of the first matching node.
| |
Returns — the value of the first node: a number when the text reads as a number, otherwise a string; Null when nothing matches. XPath functions return their own result, for example a number from count().
Remarks
- Numbers in node text are read according to the language settings of the control unit. To read a number with a decimal point regardless of them, wrap the path in the XPath function
number(). - Namespaces declared in the document are registered automatically. A prefixed namespace (
xmlns:dc="…") is used with its prefix; a default namespace (xmlns="…") gets the name of the element that declares it — for<DIDL-Lite xmlns="…">writeDIDL-Lite:container. - Documents smaller than 80 kB and compiled expressions are cached, so repeated calls on the same response are cheap.
Example — with the response holding:
| |
VAR xml := response.Content;
PARSEXML(xml, "//book[2]/title");
# Result: "Midnight Rain"
PARSEXML(xml, "//book[1]/@id");
# Result: "bk101"
PARSEXML(xml, "number(//catalog/book[1]/price)");
# Result: 44.95
PARSEXML(xml, "count(//book)");
# Result: 2
PARSEXML(xml, "//catalog/magazine[1]/price");
# Result: NullExample — XML with namespaces
VAR xml := response.Content;
PARSEXML(xml, "//DIDL-Lite:container[dc:title='My Playlist']/DIDL-Lite:res");Errors — PARSEXML - parse error: … (invalid XML or XPath).
See also — SENDHTTPREQUEST, DECODE.