Entendendo a recursividade no JSONata
A seguir, apresentaremos um exemplo que define a recursividade para navegar e transformar uma estrutura JSON. Este artigo irá detalhar o exemplo inicial e expandi-lo com explicações adicionais, exemplos práticos e casos de uso, proporcionando uma compreensão abrangente da aplicação de recursividade no JSONata.
(
$person := function($node) { $node.{"n": Name, "p":$person(Parent.Person)}};
{
"Person": Person ~> $person($)
}
)
Explicação
1. Definição da Função:
$person := function($node) { $node.{"n": Name, "p":$person(Parent.Person)}};
A linha acima define uma função recursiva chamada $person. A função recebe um nó ($node) como argumento. Ela retorna um objeto contendo:
"n": Name - A propriedade Name do nó atual.
"p": $person(Parent.Person) - O resultado da chamada da função $person na propriedade Parent.Person do nó atual, permitindo a navegação recursiva.
2. Aplicação da Função:
{
"Person": Person ~> $person($)
}
Esta parte aplica a função $person ao campo "Person" do contexto atual (denotado por $). O operador ~> canaliza o campo "Person" através da função $person.
Incrementando o Exemplo
Vamos aprimorar o exemplo adicionando mais campos para transformação e navegando em estruturas JSON mais profundamente aninhadas. Considere a seguinte estrutura JSON mais complexa:
Exemplo de JSON de Entrada
{
"Person": {
"Name": "João",
"Age": 30,
"Parent": {
"Person": {
"Name": "Maria",
"Age": 55,
"Parent": {
"Person": {
"Name": "Roberto",
"Age": 80
}
}
}
}
}
}
Função Expandida e Consulta
Vamos modificar a função para incluir a propriedade "Age" e tratar casos em que "Parent" pode estar ausente.
(
$person := function($node) {
$node.{
"n": Name,
"a": Age,
"p": $exists($person(Parent.Person)) ? $person(Parent.Person) : null
}
};
{
"Person": Person ~> $person($)
}
)
Explicação
A função modificada agora inclui "a": Age para capturar a idade de cada pessoa.
O operador ternário ($exists($person(Parent.Person)) ? ... : null) garante que a função retorne "null" se o nó não estiver presente, evitando erros ao navegar na hierarquia.
Exemplo de Saída
Aplicar a consulta expandida ao exemplo de entrada JSON resultará em:
{
"Person": {
"n": "João",
"a": 30,
"p": {
"n": "Maria",
"a": 55,
"p": {
"n": "Roberto",
"a": 80,
"p": null
}
}
}
}
Exemplos Adicionais e Casos de Uso
Exemplo com Irmãos
Vamos considerar um exemplo onde cada pessoa pode ter irmãos.
JSON de Entrada
{
"Person": {
"Name": "João",
"Age": 30,
"Siblings": [
{
"Name": "Ana",
"Age": 25
},
{
"Name": "Alex",
"Age": 28
}
],
"Parent": {
"Person": {
"Name": "Maria",
"Age": 55,
"Parent": {
"Person": {
"Name": "Roberto",
"Age": 80
}
}
}
}
}
}
Função Expandida e Consulta para Tratar Irmãos
Podemos expandir ainda mais nossa função para incluir irmãos:
(
$person := function($node) {
$node.{
"n": Name,
"a": Age,
"s": $exists($person(Siblings)) ? $person(Siblings) : null,
"p": $exists($person(Parent.Person)) ? $person(Parent.Person) : null
}
};
{
"Person": Person ~> $person($)
}
)
Explicação
A linha"s": $exists($person(Siblings)) ? $person(Siblings) : null mapeia o array Siblings e transforma cada irmão em um objeto.
Exemplo de Saída
Aplicar a consulta expandida ao exemplo de entrada JSON resultará em:
{
"Person": {
"n": "João",
"a": 30,
"s": [
{
"n": "Ana",
"a": 25,
"s": null,
"p": null
},
{
"n": "Alex",
"a": 28,
"s": null,
"p": null
}
],
"p": {
"n": "Maria",
"a": 55,
"s": null,
"p": {
"n": "Roberto",
"a": 80,
"s": null,
"p": null
}
}
}
}
Conclusão
A função recursiva no JSONata fornece uma maneira poderosa de navegar e transformar estruturas JSON aninhadas. Ao definir e aplicar tais funções, você pode percorrer dados hierárquicos, tratar campos opcionais e até mesmo mapear arrays para produzir transformações complexas e automatizadas.