Skip to content

Data Handling (JSON and CSV)

NeoObjectPascal provides native support for two of the most common data formats: JSON and CSV. Both use the same declarative syntax parse(...) into variable;, which parses a string and stores the result in a variable of type Object.

Parsing JSON

Use JSON.parse(jsonText) into variable; to convert a JSON string into an object. Then access the fields with dot notation:

npas
var dados: Object;
var jsonString: String;

begin
    jsonString := '{"nome": "Carmen", "idade": 30}';
    JSON.parse(jsonString) into dados;

    WriteLn("Nome: ", dados.nome);
    WriteLn("Idade: ", dados.idade);
end.
Saída
 Nome: Carmen Idade: 30 

Single quotes help

Because JSON uses double quotes internally, writing the string with single quotes ('...') avoids conflicts. Both quote forms are equivalent for string literals in NeoObjectPascal.

Nested objects

Dot access works at any depth of the structure:

npas
var config: Object;

begin
    config := '{"servidor": {"host": "localhost", "porta": 8080}}';
    JSON.parse(config) into config;

    WriteLn("Host: ", config.servidor.host);
    WriteLn("Porta: ", config.servidor.porta);
end.
Saída
 Host: localhost Porta: 8080 

Parsing CSV

Use CSV.parse(csvText) into variable; to convert a CSV string into a list of rows, where each row is a list of columns. The result is an Object you can iterate over:

npas
var dados: Object;
var csvString: String;

begin
    csvString := "nome,idade
Carina,30
Bruno,25";
    CSV.parse(csvString) into dados;

    // dados[0] é a primeira linha; dados[0][0] é a primeira coluna
    WriteLn("Primeira pessoa: ", dados[0][0]);
    WriteLn("Idade dela: ", dados[0][1]);
end.
Saída
 Primeira pessoa: Carina Idade dela: 30 

Iterating over the rows

Because the result of CSV.parse is iterable, you can use for..in to process each row:

npas
var linhas: Object;
var linha: Object;

begin
    linhas := "produto,preco
Cafe,12
Cha,8";
    CSV.parse(linhas) into linhas;

    for linha in linhas do
        WriteLn(linha[0], " custa ", linha[1]);
end.
Saída
 produto custa preco Cafe custa 12 Cha custa 8 

The header is a row too

CSV.parse does not distinguish the header from the data rows: the first row (produto,preco) is returned like any other. If your CSV has a header, skip index 0 when processing the data.

Combining with pipe and Java

The parsed data are ordinary values and can feed a functional pipeline or a Java block. For example, transforming a field right after parsing:

npas
function emMaiusculas(texto: String): String
begin
    return java:(texto) {
        return ((String)param0).toUpperCase();
    };
end;

var pedido: Object;

begin
    pedido := '{"cliente": "ana silva"}';
    JSON.parse(pedido) into pedido;

    WriteLn(pedido.cliente |> emMaiusculas);
end.
Saída
 ANA SILVA 

Best practices

  • Validate the origin of the data: strings coming from files or the network may be malformed. Wrap the parse in try/catch when the input is not trustworthy — see Error Handling.
  • Declare the target variable as Object, since JSON and CSV produce dynamic structures.
  • For CSV with a header, handle row 0 separately from the rest.

Next, see how to interact with the console in Input and Output.