Categorias

Você precisa conhecer YAML

YAML vai completar 20 anos em maio do ano que vem e é possível que você tenha passado as últimas duas décadas sem ter ouvido falar nessa linguagem de marcação. Grande erro!

O YAML oferece uma série de vantagens sobre seus concorrentes. Seus arquivos são mais fáceis de manipular em editores de texto, há uma boa portabilidade para linguagens de programação, oferece suporte a caracteres UNICODE etc.

André Boerseun é um arquiteto de software holandês, com larga experiência em diversas empresas, que ele compartilha em seu blog pessoal. Em um artigo publicado na internet, ele apresenta os princípios fundamentais do YAML e sua complexa sintaxe.

Com sua autorização, traduzimos e reproduzimos o artigo na íntegra:

“Originalmente, YAML era um acrônimo para Yet Another Markup Language, já que seu propósito original era ser uma linguagem de marcação de documento. Os três autores, Clark Evans, Ingy döt Net e Oren Ben-Kiki se juntaram em 2001 percebendo que os projetos em que trabalharam têm muito em comum. Eles combinaram seu trabalho em um único projeto conhecido como YAML, uma linguagem de serialização de dados. Eles renomearam YAML para YAML Ain’t Markup Language, que também é um acrônimo recursivo.

YAML é comumente usado para arquivos de configuração e em aplicativos onde os dados estão sendo armazenados ou transmitidos. YAML tem tipos de dados muito simplistas (escalares, listas, arrays ..) e estruturas de dados (indentação, travessões, dois pontos ..). A extensão de um arquivo yaml pode ser yml ou yaml.

Sintaxe YAML

Sintaxe básica

A sintaxe YAML usa recuo para uma estrutura (2 espaços, não tabulações), travessões para listas e dois pontos para pares de valores-chave. Nenhuma chave duplicada é permitida no mesmo nível.

As sequências são listas:

- Item 1
- Item 2

Os mapeamentos são pares de valores-chave:

key1: value1
key2: value2

Uma sequência de mapeamentos:

- key1: value1
  key2: value2

Um mapeamento de mapeamentos:

overallkey:
  key1: value1
  key2: value2

O estilo de bloco emprega recuo em vez de indicadores para denotar a estrutura. Isso resulta em uma notação mais legível (embora menos compacta), mas também é menos compacta.

student: "Joe Soap"
university: 
  city: Pretoria
  country: South-Africa
  name: Tukkies
courses: 
  - "Computer Science"
  - Mathematics
  - Physics

O estilo de fluxo pode ser considerado a extensão natural do JSON para cobrir a quebra de longas linhas de conteúdo para facilitar a leitura, marcar nós para controlar a construção de estruturas de dados nativas e usar âncoras e aliases para reutilizar instâncias de objetos construídos.

student: "Joe Soap"
university: { name: Tukkies, city: Pretoria, country: South-Africa}
courses: [Computer Science, Mathematics, Physics]

Comentários

Um comentário explícito é marcado por um indicador “#”. Os comentários devem ser separados de outros tokens por caracteres de espaço em branco. Os comentários são um detalhe da apresentação e não devem ser usados ​​para transmitir informações de conteúdo.

# isso é um comentário
students: # esse é um comentário na linha
  - Mark McGwire
  - Sammy Sosa
teachers:
  # esse é um comentário na linha
  - Sammy Sosa
  - Ken Griffey

Escalares

YAML fornece três estilos escalares de fluxo: aspas duplas, aspas simples e simples (sem aspas). O estilo de aspas duplas é especificado pelos indicadores . Este é o único estilo capaz de expressar strings arbitrárias, usando sequências de escape. O estilo entre aspas simples é especificado pelos indicadores ao redor. Portanto, em um escalar entre aspas simples, esses caracteres precisam ser repetidos.O estilo simples (sem aspas) não tem indicadores de identificação e não fornece nenhuma forma de escape.

O escalar representa strings, inteiros, datas e outros tipos de dados atômicos.

strings:
  - double-quoted: "Esse é o valor de uma string"
  - single-quoted: 'Esse é o valor de uma string'
  - unquoted: Esse é o valor de uma string
nulls: 
  - null
  - ~ 
booleans:
  - true: true          # outros valores possíveis são { Y, true, Yes, ON  }
  - false: false        # outros valores possíveis são { n, FALSE, No, off }
integers:
  - canonical: 12345
  - decimal: +12345
  - octal: 0o14
  - hexadecimal: 0xC
floating-point:
  - canonical: 1.23015e+3
  - exponential: 12.3015e+02
  - fixed: 1230.15
  - negative_infinity: -.inf
  - not_a_number: .NaN
timestamps:
  - canonical: 2001-12-15T02:59:43.1Z
  - iso8601: 2001-12-14t21:59:43.10-05:00
  - spaced: 2001-12-14 21:59:43.10 -5
  - date: 2002-12-14
block-notation: | 
  Conteúdo escalar pode ser escrito em notação de bloco, 
  usando um estilo literal (indicado por `|`) onde
  todas as quebras de linha são importantes.
folded-style: >
  Conteúdo escalar pode ser escrito com o
  estilo dobrado (indicado por `>`) onde cada 
  quebra de linha é dobrada para um espaço a menos que
  termine no vazio ou em uma linha com mais identação.

Estruturas

YAML usa três travessões () para separar as diretivas do conteúdo do documento. Isso também serve para sinalizar o início de um documento se nenhuma diretiva estiver presente. Três pontos () indicam o final de um documento sem iniciar um novo, para uso em canais de comunicação.

---
# Directive 1
cluster_name: 'Test Cluster'
num_tokens: 256
listen_address: localhost
---
# Directive 2
cluster_name: 'Production Cluster'
num_tokens: 1024
listen_address: 192.168.10.1
...

Tag

As tags são usadas para definir um URI personalizado, definir tags locais e definir um tipo de dados.

As tags globais são URIs e, portanto, globalmente exclusivas em todos os aplicativos. O esquema tag: URI é recomendado para todas as tags YAML globais.

As tags locais são específicas para um único aplicativo. As tags locais começam com !, Não são URIs e não se espera que sejam globalmente exclusivas. YAML fornece uma diretiva TAG para tornar a notação de tag menos detalhada

%TAG ! tag:javanibble.com,2020:
--- !shape 
- !circle       # tag:javanibble.com,2020:circle
  center: {x: 73, y: 129}
  radius: 7

- !line         # tag:javanibble.com,2020:line
  start: {x: 73, y: 129}
  finish: { x: 89, y: 102 }

- !label        # tag:javanibble.com,2020:label
  start: {x: 73, y: 129}
  color: 0xFFEEBB
  text: Pretty vector drawing.

A digitação explícita é denotada com uma tag usando o símbolo do ponto de exclamação (!).

  • !!map : { tabela de hashes, dicionário, mapeamento}
  • !!seq : { listas, arrays, vetores, sequências }
  • !!str : string Unicode
  • !!set : { cerejas, ameixas, maçãs }
  • !!omap : [ one: 1, two: 2 ]
  • !!bool : {true, false}
  • !!null : {null}
  • !!int : números negativos (-12), zero (0), números positivos (34)
  • !!float: números negativos (-12.4), zero (0), números positivos (34.7), infinito (.inf), not a number (.nan)
!!map {
  ? !!str "sequence"
  : !!seq [ !!str "one", !!str "two" ],
  ? !!str "mapping"
  : !!map {
    ? !!str "sky" : !!str "blue",
    ? !!str "sea" : !!str "green",
  },
}

# This is equal to:
sequence: 
  - one
  - two
mapping: 
  sea: green
  sky: blue

Âncoras

Uma âncora é denotada pelo indicador &. Ele marca um nó para referência futura. Um nó ancorado não precisa ser referenciado por nenhum nó alias. Um nó de alias é denotado pelo indicador *. O alias se refere ao nó anterior mais recente com a mesma âncora.

- center: &ORIGIN {x: 73, y: 129}
  radius: 7
- start: *ORIGIN
  finish: { x: 89, y: 102 }
- start: *ORIGIN
  color: 0xFFEEBB
  text: Pretty vector drawing.

Indicadores

Indicadores são caracteres que têm semântica especial:

  •  (hífen) indica uma entrada de sequência de bloco.
  • ? (ponto de interrogação) indica um mapeamento de chave.
  • : (dois pontos) indica um mapeamento de valor.
  • , (vírgula) termina uma entrada de coleta de fluxo.
  • [ (colchete esquerdo) inicia uma sequência de fluxo.
  • ] (colchete direito) encerra uma sequência de fluxo.
  • { (chave esquerda) inicia um mapeamento de fluxo.
  • } (chave direita) encerra um mapeamento de fluxo.
  • # (tralha) indica um comentário.
  • & (“e comercial” ou ampersand) indica uma propriedade de âncora do nó.
  • * (asterisco) indica  um nó de alias.
  • ! (ponto de exclamação) indica tags de nó.
  • | (barra vertical) indica um bloco escalar literal.
  • > (maior que) indica um bloco escalar com dobra.
  • (apóstrofo ou aspa simples) envolve um fluxo escalar.
  • (aspas dupla) envove um fluxo escalar.
  • % (porcentagem) indica uma linha diretiva.

Exemplo de YAML

A seguir está um exemplo de uma fatura definida em YAML. A estrutura da fatura é mostrada através de indentação (2 espaços), a sequência ou lista de itens são denotados por um travessão e, por fim, todos os pares de valores-chave são denotados por dois pontos.

# Invoice for shipping to the USA.
invoice_nr: `123456`
date: 2020-08-24
company:
  name: The LEGO Group
  address: 
    lines: |
      Højmarksvej 8
      DK-7190 Billund
    country: Denmark
    phone: +45 79 50 60 70
bill_to: &id0001
  contact_person: Amanda Stewart
  client_company: 
    name: Lego World
    address:
      street: 125  Modoc Alley
      city: TERLINGUA
      state: TX 
      zip_code: 79852
ship_to: *id0001
product_items:
  - sku: PI1324A
    description: LEGO NINJAGO Spinjitzu Burst Lloyd - 70687
    quantity: 100
    unit_price: 9,99
    total: 999,00
  - sku: PI1324B
    description: LEGO NINJAGO Spinjitzu Burst Cole - 70685 
    quantity: 100
    unit_price: 9,99
    total: 999,00
tax: 278,00
total: 1998,00
notes: >
  Please only deliver during office hours.
  Ask for Jane Soap at the front desk.
  Alternative contact number is 555-1232

Referências e links

Publicado originalmente como “YAML Essentials” em 23 de agosto de 2020. Traduzido e republicado com autorização do autor.