Formateando Texto JSON en Business Central: Una Guía Completa

Descubre cómo formatear un texto JSON de manera clara y legible utilizando un procedimiento en AL para Microsoft Dynamics 365 Business Central.

En el desarrollo de Business Central, el manejo de datos en formato JSON es algo habitual, especialmente al trabajar con integraciones y servicios externos. Sin embargo, leer un JSON sin formato puede ser una tarea ardua. Por ello, he creado un procedimiento que convierte un texto JSON en una estructura clara y legible.

¡Vamos manos a la obra! 😌


🔍 Código Completo

Aquí tienes el procedimiento completo que permite formatear un texto JSON en Business Central:

// Procedimiento que da formato a un texto JSON.
// Se lee el texto JSON, se recorre su estructura y se genera un nuevo texto formateado.
procedure FormatJsonText(JsonText: Text): Text
var
    TempJsonBuffer: Record "JSON Buffer" temporary;
    JsonTextReaderWriter: Codeunit "Json Text Reader/Writer";
    LastPropertyName: Text;
    FormattedJson: Text;
begin
    // Se lee el texto JSON y se carga en el buffer temporal.
    JsonTextReaderWriter.ReadJSonToJSonBuffer(JsonText, TempJsonBuffer);

    // Se recorre el buffer si tiene registros.
    if TempJsonBuffer.FindSet() then
        repeat
            // Se evalúa el tipo de token para determinar la acción correspondiente.
            case TempJsonBuffer."Token type" of
                // Se almacena el nombre de la propiedad para su uso posterior.
                TempJsonBuffer."Token type"::"Property Name":
                    LastPropertyName := TempJsonBuffer.Value;

                // Se inicia un nuevo objeto JSON.
                TempJsonBuffer."Token type"::"Start Object":
                    if LastPropertyName <> '' then begin
                        JsonTextReaderWriter.WriteStartObject(LastPropertyName);
                        LastPropertyName := '';
                    end else
                        JsonTextReaderWriter.WriteStartObject('');

                // Se cierra un objeto JSON.
                TempJsonBuffer."Token type"::"End Object":
                    JsonTextReaderWriter.WriteEndObject();

                // Se inicia un nuevo array JSON.
                TempJsonBuffer."Token type"::"Start Array":
                    if LastPropertyName <> '' then begin
                        JsonTextReaderWriter.WriteStartArray(LastPropertyName);
                        LastPropertyName := '';
                    end else
                        JsonTextReaderWriter.WriteStartArray('');

                // Se cierra un array JSON.
                TempJsonBuffer."Token type"::"End Array":
                    JsonTextReaderWriter.WriteEndArray();

                // Se escribe una propiedad de tipo cadena.
                TempJsonBuffer."Token type"::String:
                    if LastPropertyName <> '' then begin
                        JsonTextReaderWriter.WriteStringProperty(LastPropertyName, TempJsonBuffer.Value);
                        LastPropertyName := '';
                    end else
                        JsonTextReaderWriter.WriteValue(TempJsonBuffer.Value);

                // Se escribe una propiedad de tipo numérico (entero o decimal).
                TempJsonBuffer."Token type"::Integer,
                TempJsonBuffer."Token type"::Decimal:
                    if LastPropertyName <> '' then begin
                        JsonTextReaderWriter.WriteNumberProperty(LastPropertyName, TempJsonBuffer.Value);
                        LastPropertyName := '';
                    end else
                        JsonTextReaderWriter.WriteValue(TempJsonBuffer.Value);

                // Se escribe una propiedad de tipo booleano.
                TempJsonBuffer."Token type"::Boolean:
                    if LastPropertyName <> '' then begin
                        JsonTextReaderWriter.WriteBooleanProperty(LastPropertyName, TempJsonBuffer.Value);
                        LastPropertyName := '';
                    end else
                        JsonTextReaderWriter.WriteValue(TempJsonBuffer.Value);

                // Se escribe una propiedad con valor nulo.
                TempJsonBuffer."Token type"::Null:
                    if LastPropertyName <> '' then begin
                        JsonTextReaderWriter.WriteNullProperty(LastPropertyName);
                        LastPropertyName := '';
                    end else
                        JsonTextReaderWriter.WriteNullValue();
            end;
        until TempJsonBuffer.Next() = 0;

    // Se obtiene el texto JSON formateado.
    FormattedJson := JsonTextReaderWriter.GetJSonAsText();
    exit(FormattedJson);
end;

📖 Análisis Detallado del Código

Este procedimiento recorre un texto JSON, identifica su estructura y lo vuelve a escribir con formato. A continuación, se detalla el funcionamiento paso a paso.

1️⃣ Declaración de Variables

var
    TempJsonBuffer: Record "JSON Buffer" temporary;
    JsonTextReaderWriter: Codeunit "Json Text Reader/Writer";
    LastPropertyName: Text;
    FormattedJson: Text;
  • TempJsonBuffer: Registro temporal para almacenar la estructura del JSON.
  • JsonTextReaderWriter: Codeunit que se encarga de leer y escribir JSON.
  • LastPropertyName: Almacena el nombre de la última propiedad leída.
  • FormattedJson: Contendrá el resultado final con formato.

2️⃣ Lectura del Texto JSON

JsonTextReaderWriter.ReadJSonToJSonBuffer(JsonText, TempJsonBuffer);

Se utiliza el JsonTextReaderWriter para leer el texto JSON y cargar su contenido en el TempJsonBuffer. Este paso es fundamental para recorrer la estructura después.


3️⃣ Recorrido del Buffer

if TempJsonBuffer.FindSet() then
    repeat

Esta estructura permite recorrer el buffer si contiene registros. Por cada registro encontrado, se evalúa el tipo de token.


4️⃣ Análisis del Token

La estructura case es el núcleo del procedimiento. Evalúa el tipo de token y ejecuta la acción correspondiente.

🏷️ Propiedades

TempJsonBuffer."Token type"::"Property Name":
    LastPropertyName := TempJsonBuffer.Value;

Cuando se encuentra un nombre de propiedad, se guarda para utilizarlo al asignar el valor correspondiente.


📦 Objetos

  • Inicio de un objeto:
TempJsonBuffer."Token type"::"Start Object":
    if LastPropertyName <> '' then begin
        JsonTextReaderWriter.WriteStartObject(LastPropertyName);
        LastPropertyName := '';
    end else
        JsonTextReaderWriter.WriteStartObject('');

Si existe un nombre de propiedad, el objeto se asocia a esta. De lo contrario, se inicia un objeto sin nombre.

  • Fin de un objeto:
TempJsonBuffer."Token type"::"End Object":
    JsonTextReaderWriter.WriteEndObject();

Se cierra el objeto actual.


🔢 Arrays

  • Inicio de un array:
TempJsonBuffer."Token type"::"Start Array":
    if LastPropertyName <> '' then begin
        JsonTextReaderWriter.WriteStartArray(LastPropertyName);
        LastPropertyName := '';
    end else
        JsonTextReaderWriter.WriteStartArray('');

Funciona igual que para los objetos, pero en este caso se inicia un array.

  • Fin de un array:
TempJsonBuffer."Token type"::"End Array":
    JsonTextReaderWriter.WriteEndArray();

Se cierra el array actual.


🖋️ Valores de Distintos Tipos

  • Cadenas:
TempJsonBuffer."Token type"::String:
    if LastPropertyName <> '' then begin
        JsonTextReaderWriter.WriteStringProperty(LastPropertyName, TempJsonBuffer.Value);
        LastPropertyName := '';
    end else
        JsonTextReaderWriter.WriteValue(TempJsonBuffer.Value);

Si hay una propiedad asociada, se escribe como una propiedad de tipo cadena. Si no, simplemente se escribe el valor.

  • Números (enteros y decimales):
TempJsonBuffer."Token type"::Integer,
TempJsonBuffer."Token type"::Decimal:
    if LastPropertyName <> '' then begin
        JsonTextReaderWriter.WriteNumberProperty(LastPropertyName, TempJsonBuffer.Value);
        LastPropertyName := '';
    end else
        JsonTextReaderWriter.WriteValue(TempJsonBuffer.Value);

Mismo funcionamiento que con las cadenas, pero aplicando el tipo numérico.

  • Booleanos:
TempJsonBuffer."Token type"::Boolean:
    if LastPropertyName <> '' then begin
        JsonTextReaderWriter.WriteBooleanProperty(LastPropertyName, TempJsonBuffer.Value);
        LastPropertyName := '';
    end else
        JsonTextReaderWriter.WriteValue(TempJsonBuffer.Value);

Se aplican las mismas reglas, adaptando el método de escritura para valores booleanos.

  • Nulos:
TempJsonBuffer."Token type"::Null:
    if LastPropertyName <> '' then begin
        JsonTextReaderWriter.WriteNullProperty(LastPropertyName);
        LastPropertyName := '';
    end else
        JsonTextReaderWriter.WriteNullValue();

Si el valor es nulo, se escribe como null.


5️⃣ Finalización y Resultado

Una vez recorridos todos los registros del buffer, se obtiene el JSON formateado:

FormattedJson := JsonTextReaderWriter.GetJSonAsText();
exit(FormattedJson);

Este texto se devuelve como resultado final.


🎯 Beneficios y Aplicaciones Prácticas

Este procedimiento es útil para:

  • Depurar JSON: facilita la comprensión del contenido.
  • Integraciones externas: al formatear datos recibidos de servicios web.
  • Presentación clara: útil cuando se necesita almacenar o mostrar el JSON formateado.

En entornos donde se manejan integraciones complejas, disponer de un texto JSON legible puede ahorrar mucho tiempo a los desarrolladores.


🧠 Conclusión

Formatear un texto JSON en Business Central no tiene por qué ser complicado. Con este procedimiento, puedes convertir una estructura difícil de leer en un formato comprensible de manera eficiente.

Si quieres ver el código completo, está en GitHub.

Share your love

Leave a Reply

Your email address will not be published. Required fields are marked *