2.4. Function Extensions (Estensioni di funzione)
2.4. Function Extensions (Estensioni di funzione)
Oltre alla funzionalità delle espressioni di filtro definita nelle sottosezioni precedenti, JSONPath definisce un punto di estensione che può essere usato per aggiungere funzionalità alle espressioni di filtro: "Function Extensions".
Questa sezione definisce il punto di estensione e alcune function extensions che usano tale punto. Sebbene questi meccanismi siano progettati per usare il punto di estensione, sono parte integrante della specifica JSONPath e ci si attende che siano implementati come qualsiasi altra parte integrante di questa specifica.
Una function extension definisce un nome registrato (vedere Sezione 3.2) che può essere applicato a una sequenza di zero o più argomenti, producendo un risultato. Ciascun nome di funzione registrato è univoco.
Una function extension DEVE essere definita in modo che la sua valutazione sia priva di effetti collaterali, vale a dire tutti gli ordini possibili di valutazione e le scelte di cortocircuito o valutazione completa di un'espressione che la contiene DEVONO condurre allo stesso risultato. (Nota: la memoizzazione o il logging non sono effetti collaterali in questo senso poiché sono visibili solo a livello di implementazione, non influenzano il risultato della valutazione.)
function-name = function-name-first *function-name-char
function-name-first = LCALPHA
function-name-char = function-name-first / "_" / DIGIT
LCALPHA = %x61-7A ; "a".."z"
function-expr = function-name "(" S [function-argument
*(S "," S function-argument)] S ")"
function-argument = literal /
filter-query / ; (includes singular-query)
logical-expr /
function-expr
Qualsiasi function expression in un'interrogazione deve essere ben formata (conforme all'ABNF sopra) e ben tipizzata; altrimenti, l'implementazione JSONPath DEVE segnalare un errore (vedere Sezione 2.1). Per definire quali function expression sono ben tipizzate, si introduce prima un sistema di tipi.
2.4.1. Type System for Function Expressions (Sistema di tipi per le espressioni di funzione)
Ciascun parametro e il risultato di una function extension devono avere un tipo dichiarato.
I tipi dichiarati consentono di verificare un'interrogazione JSONPath per la correttezza di tipo indipendentemente da qualsiasi argomento dell'interrogazione a cui l'interrogazione JSONPath è applicata.
La Tabella 13 definisce i tipi disponibili in termini delle istanze che contengono.
| Tipo | Istanze |
|---|---|
| ValueType | Valori JSON o Nothing |
| LogicalType | LogicalTrue o LogicalFalse |
| NodesType | Nodelist |
Tabella 13: Sistema di tipi delle function extension
Note:
- Le sole istanze che possono essere rappresentate direttamente nella sintassi
JSONPath sono certi valori JSON in ValueType espressi come letterali (che, in JSONPath, sono limitati a valori primitivi).
- Il risultato speciale Nothing rappresenta l'assenza di un valore JSON
ed è distinto da qualsiasi valore JSON, incluso null.
- LogicalTrue e LogicalFalse non sono correlati ai valori JSON
espressi dai letterali true e false.
2.4.2. Type Conversion (Conversione di tipo)
Proprio come le interrogazioni possono essere usate in espressioni logiche verificando l'esistenza di almeno un nodo (Sezione 2.3.5.2.1), una function expression di tipo dichiarato NodesType può essere usata come function argument per un parametro di tipo dichiarato LogicalType, con la regola di conversione equivalente:
- Se la nodelist contiene uno o più nodi, il risultato della conversione
è LogicalTrue.
- Se la nodelist è vuota, il risultato della conversione è LogicalFalse.
Note:
- L'estrazione di un valore da una nodelist può essere eseguita in diversi
modi, quindi una conversione implicita da NodesType a ValueType può sorprendere e non è stata definita.
- Una function expression con tipo dichiarato NodesType può
indirettamente essere usata come argomento per un parametro di tipo dichiarato ValueType racchiudendo l'espressione in una chiamata a una function extension, come value() (vedere Sezione 2.4.8), che prende un parametro di tipo NodesType e restituisce un risultato di tipo ValueType.
La correttezza di tipo delle function expression può ora essere definita in termini di questo sistema di tipi.
2.4.3. Well-Typedness of Function Expressions (Correttezza di tipo delle espressioni di funzione)
Affinché una function expression sia ben tipizzata:
- Il suo tipo dichiarato deve essere ben tipizzato nel contesto in cui compare.
Come da grammatica, una function expression può comparire in tre contesti immediati diversi, che conducono alle seguenti condizioni per la correttezza di tipo:
Come test-expr in un'espressione logica: il tipo di risultato dichiarato della funzione è LogicalType o (dando luogo a conversione come da Sezione 2.4.2) NodesType.
Come comparable in un confronto: il tipo di risultato dichiarato della funzione è ValueType.
Come function-argument in un'altra function expression: il tipo di risultato dichiarato della funzione soddisfa le seguenti regole per il parametro corrispondente della funzione racchiudente.
- I suoi argomenti devono essere ben tipizzati per il tipo dichiarato dei parametri corrispondenti.
Gli argomenti della function expression sono ben tipizzati quando ciascun argomento della funzione può essere usato per il tipo dichiarato del parametro corrispondente, secondo una delle seguenti condizioni:
- Quando l'argomento è una function expression con lo stesso
tipo di risultato dichiarato del tipo dichiarato del parametro.
- Quando il tipo dichiarato del parametro è LogicalType e l'
argomento è uno dei seguenti:
- Una function expression con tipo di risultato dichiarato NodesType.
In questo caso, l'argomento è convertito in LogicalType come da Sezione 2.4.2.
-
Una logical-expr che non è una function expression.
-
Quando il tipo dichiarato del parametro è NodesType e l'
argomento è un'interrogazione (che include singular query).
- Quando il tipo dichiarato del parametro è ValueType e l'
argomento è uno dei seguenti:
-
Un valore espresso come letterale.
-
Una singular query. In questo caso:
o Se l'interrogazione produce una nodelist costituita da un singolo nodo, l'argomento è il valore del nodo.
o Se l'interrogazione produce una nodelist vuota, l'argomento è il risultato speciale Nothing.
2.4.4. length() Function Extension (Estensione di funzione length())
Parametri: 1. ValueType
Risultato: ValueType (intero senza segno o Nothing)
La function extension length() fornisce un modo per calcolare la lunghezza di un valore e renderla disponibile per ulteriore elaborazione nell'espressione di filtro:
$[?length(@.authors) >= 5]
Il suo unico argomento è un'istanza di ValueType (eventualmente presa da una singular query, come nell'esempio sopra). Il risultato è anche un'istanza di ValueType: un intero senza segno o il risultato speciale Nothing.
- Se il valore dell'argomento è una stringa, il risultato è il numero di
valori scalari Unicode nella stringa.
- Se il valore dell'argomento è un array, il risultato è il numero di
elementi nell'array.
- Se il valore dell'argomento è un oggetto, il risultato è il numero di
membri nell'oggetto.
- Per qualsiasi altro valore dell'argomento, il risultato è il risultato speciale
Nothing.
2.4.5. count() Function Extension (Estensione di funzione count())
Parametri: 1. NodesType
Risultato: ValueType (intero senza segno)
La function extension count() fornisce un modo per ottenere il numero di nodi in una nodelist e renderlo disponibile per ulteriore elaborazione nell'espressione di filtro:
$[?count(@.*.author) >= 5]
Il suo unico argomento è una nodelist. Il risultato è un valore (un intero senza segno) che dà il numero di nodi nella nodelist.
Note:
-
Non c'è deduplicazione della nodelist.
-
Il numero di nodi nella nodelist è contato indipendentemente dai
loro valori o da eventuali figli che possono avere, ad esempio il conteggio di una nodelist singolare non vuota come count(@) è sempre 1.
2.4.6. match() Function Extension (Estensione di funzione match())
Parametri: 1. ValueType (stringa)
- ValueType (stringa conforme a [RFC9485])
Risultato: LogicalType
La function extension match() fornisce un modo per verificare se (per intero; vedere Sezione 2.4.7) una data stringa corrisponde a una data espressione regolare, che è nella forma descritta in [RFC9485].
$[?match(@.date, "1974-05-..")]
I suoi argomenti sono istanze di ValueType (eventualmente prese da una singular query, come per il primo argomento nell'esempio sopra). Se il primo argomento non è una stringa o il secondo argomento non è una stringa conforme a [RFC9485], il risultato è LogicalFalse. Altrimenti, la stringa che è il primo argomento è confrontata con l'I-Regexp contenuta nella stringa che è il secondo argomento; il risultato è LogicalTrue se la stringa corrisponde all'I-Regexp ed è LogicalFalse altrimenti.
2.4.7. search() Function Extension (Estensione di funzione search())
Parametri: 1. ValueType (stringa)
- ValueType (stringa conforme a [RFC9485])
Risultato: LogicalType
La function extension search() fornisce un modo per verificare se una data stringa contiene una sottostringa che corrisponde a una data espressione regolare, che è nella forma descritta in [RFC9485].
$[?search(@.author, "[BR]ob")]
I suoi argomenti sono istanze di ValueType (eventualmente prese da una singular query, come per il primo argomento nell'esempio sopra). Se il primo argomento non è una stringa o il secondo argomento non è una stringa conforme a [RFC9485], il risultato è LogicalFalse. Altrimenti, nella stringa che è il primo argomento si cerca una sottostringa che corrisponde all'I-Regexp contenuta nella stringa che è il secondo argomento; il risultato è LogicalTrue se esiste almeno una tale sottostringa ed è LogicalFalse altrimenti.
2.4.8. value() Function Extension (Estensione di funzione value())
Parametri: 1. NodesType
Risultato: ValueType
La function extension value() fornisce un modo per convertire un'istanza di NodesType in un valore e renderlo disponibile per ulteriore elaborazione nell'espressione di filtro:
$[?value(@..color) == "red"]
Il suo unico argomento è un'istanza di NodesType (eventualmente presa da una filter-query, come nell'esempio sopra). Il risultato è un'istanza di ValueType.
- Se l'argomento contiene un singolo nodo, il risultato è il valore del
nodo.
- Se l'argomento è la nodelist vuota o contiene più nodi,
il risultato è Nothing.
Nota: una singular query può essere usata ovunque sia atteso un ValueType, quindi non è necessario usare la function extension value() con una singular query.
2.4.9. Examples (Esempi)
| Query | Commento |
|---|---|
| $[?length(@) < 3] | ben tipizzata |
| $[?length(@.*) < 3] | non ben tipizzata poiché @.* è un' |
| interrogazione non singolare | |
| $[?count(@.*) == 1] | ben tipizzata |
| $[?count(1) == 1] | non ben tipizzata poiché 1 non è un'interrogazione né |
| function expression | |
| $[?count(foo(@.*)) | ben tipizzata, dove foo() è una function |
| == 1] | extension con parametro di tipo |
| NodesType e tipo di risultato NodesType | |
| $[?match(@.timezone, | ben tipizzata |
| 'Europe/.*')] | |
| $[?match(@.timezone, | non ben tipizzata poiché LogicalType non può essere |
| 'Europe/.*') == | usato nei confronti |
| true] | |
| $[?value(@..color) | ben tipizzata |
| == "red"] | |
| $[?value(@..color)] | non ben tipizzata poiché ValueType non può essere |
| usato in un'espressione di test | |
| $[?bar(@.a)] | ben tipizzata per qualsiasi funzione bar() con un |
| parametro di qualsiasi tipo dichiarato e | |
| tipo di risultato LogicalType | |
| $[?bnl(@.*)] | ben tipizzata per qualsiasi funzione bnl() con |
| parametro di tipo dichiarato NodesType o | |
| LogicalType e tipo di risultato LogicalType | |
| $[?blt(1==1)] | ben tipizzata, dove blt() è una function |
| con parametro di tipo dichiarato | |
| LogicalType e tipo di risultato LogicalType | |
| $[?blt(1)] | non ben tipizzata per la stessa function |
| blt(), poiché 1 non è un'interrogazione, logical- | |
| expr, o function expression | |
| $[?bal(1)] | ben tipizzata, dove bal() è una function |
| con parametro di tipo dichiarato | |
| ValueType e tipo di risultato LogicalType |
Tabella 14: Esempi di espressioni di funzione