Æ, ø og å: tegnsæt og URL-kodning

Send æøå korrekt URL-kodet, læs UTF-8-svar uden ødelagte tegn, åbn CSV i Excel med de rigtige bogstaver, og forstå oe/aa/ae-foldningen i autocomplete.

4 min Niveau: Begynder ✓ Kode testet

Danske adresser er fulde af æ, ø og å. API'et bruger UTF-8 hele vejen: i URL'en, i JSON og i CSV. Problemer opstår, når et led i kæden bruger et andet tegnsæt, typisk Windows-1252 (også kaldet Latin-1 eller ANSI). Resultatet er enten tomme svar eller tekst som RÃ¥dhuspladsen.

Genkend fejlen

Du serDet skulle væreÅrsag
æ, ø, Ã¥æ, ø, åUTF-8 læst som Windows-1252
Æ, Ø, Ã…Æ, Ø, ÅDet samme med store bogstaver
� eller ?æ, ø eller åWindows-1252 læst som UTF-8, eller tegnet tabt ved en konvertering
R%E5dhuspladsen i URL'enR%C3%A5dhuspladsenTeksten er URL-kodet som Latin-1
å i JSONåIkke en fejl. JSON-parseren laver det om til å

Send æøå i URL'en

I en URL skal æ, ø og å sendes som UTF-8-bytes, procentkodet:

TegnURL-kodet
æ / Æ%C3%A6 / %C3%86
ø / Ø%C3%B8 / %C3%98
å / Å%C3%A5 / %C3%85
mellemrum%20 (eller + i query-strengen)

Byg aldrig URL'en ved at sætte tekst sammen. Lad dit bibliotek kode parametrene. Med curl gør -G og --data-urlencode det for dig:

Shell#curl-urlencode
curl -s -G "https://api.danadresse.dk/autocomplete" \
  --data-urlencode "q=Rådhuspladsen 1" \
  --data-urlencode "per_side=3" \
  -H "X-Api-Key: $DANADRESSE_API_KEY"

I Python koder requests alt, du giver det i params:

Python#python-params
import os
import requests

r = requests.get(
    "https://api.danadresse.dk/autocomplete",
    params={"q": "Rådhuspladsen 1", "per_side": 1},
    headers={"X-Api-Key": os.environ["DANADRESSE_API_KEY"]},
    timeout=10,
)
r.raise_for_status()
print(r.url)                              # ...?q=R%C3%A5dhuspladsen+1&per_side=1
print(r.json()[0]["forslagstekst"])       # r.json() læser altid UTF-8

I PHP bruger du http_build_query, som koder UTF-8-strenge korrekt. Brug ikke utf8_decode eller mb_convert_encoding til Latin-1 før kaldet:

PHP#php-build-query
<?php
$query = http_build_query(["q" => "Rådhuspladsen 1", "per_side" => 3]);
$ctx = stream_context_create(["http" => [
    "header" => "X-Api-Key: " . getenv("DANADRESSE_API_KEY"),
    "timeout" => 10,
]]);
$body = file_get_contents("https://api.danadresse.dk/autocomplete?$query", false, $ctx);
foreach (json_decode($body, true) as $forslag) {
    echo $forslag["forslagstekst"], "\n";
}

I JavaScript bruger du URL og searchParams.set(), som i Dit første API-kald.

Kommer din tekst fra et gammelt system, en fil eller en database i Windows-1252, så konverter den til UTF-8, før du sender den. I Python: tekst = rå_bytes.decode("cp1252"). På kommandolinjen: iconv -f WINDOWS-1252 -t UTF-8 ind.csv > ud.csv.

Læs svaret som UTF-8

JSON-svar har Content-Type: application/json uden en charset-parameter. JSON er altid UTF-8, og de fleste klienter ved det: r.json() i Python, res.json() i JavaScript og json_decode() i PHP giver de rigtige tegn.

Problemerne kommer, når en klient gætter tegnsættet ud fra headeren:

  • Windows PowerShell 5.1 (Invoke-RestMethod, Invoke-WebRequest) læser et svar uden charset som Latin-1. Brug PowerShell 7, eller læs bytes og dekod dem selv:
PowerShell#powershell-utf8
$headers = @{ "X-Api-Key" = $env:DANADRESSE_API_KEY }
$res = Invoke-WebRequest -Uri "https://api.danadresse.dk/postnumre/2900" -Headers $headers -UseBasicParsing
$json = [System.Text.Encoding]::UTF8.GetString($res.RawContentStream.ToArray()) | ConvertFrom-Json
$json.navn
  • Ældre HTTP-biblioteker i fx Java, .NET eller VBA bruger systemets standardtegnsæt, når de laver bytes om til tekst. Angiv UTF-8 eksplicit.
  • Databasen skal også kunne gemme tegnene. I MySQL og MariaDB skal kolonnen og forbindelsen være utf8mb4.

CSV i Excel

format=csv giver UTF-8 uden BOM (byte order mark). Dobbeltklikker du på filen i Excel på Windows, gætter Excel på Windows-1252, og så står der RÃ¥dhuspladsen. Der er tre løsninger:

  1. Importér i stedet for at åbne. I Excel: Data → Fra tekst/CSV, vælg filen, og sæt Filoprindelse til 65001: Unicode (UTF-8).
  2. Power Query. Angiv tegnsættet direkte:
Power Query (M)#power-query-csv
let
    Kilde = Web.Contents(
        "https://api.danadresse.dk/adresser",
        [Query = [postnr = "4200", per_side = "100", format = "csv"],
         Headers = [#"X-Api-Key" = "DIN_API_NØGLE"]]),
    Csv = Csv.Document(Kilde, [Delimiter = ",", Encoding = 65001, QuoteStyle = QuoteStyle.Csv]),
    Tabel = Table.PromoteHeaders(Csv, [PromoteAllScalars = true])
in
    Tabel
  1. Gem filen med BOM. Henter du CSV'en med et script, så skriv den med en BOM foran. Så åbner Excel den rigtigt ved dobbeltklik:
Python#csv-with-bom
import os

import requests

r = requests.get(
    "https://api.danadresse.dk/adresser",
    params={"postnr": "4200", "per_side": 1000, "format": "csv"},
    headers={"X-Api-Key": os.environ["DANADRESSE_API_KEY"]},
    timeout=30,
)
r.raise_for_status()
with open("adresser.csv", "w", encoding="utf-8-sig", newline="") as f:  # utf-8-sig = UTF-8 med BOM
    f.write(r.content.decode("utf-8"))
print("Gemte adresser.csv")

Excel med dansk opsætning forventer semikolon som skilletegn. API'ets CSV bruger komma, så vælg komma i importdialogen, eller brug Power Query som ovenfor. Se også Excel og Power Query.

oe, aa og ae i autocomplete

Brugere skriver ofte uden danske tegn: raadhuspladsen, kobenhavn, Soendergade. /autocomplete prøver derfor varianter af det, brugeren har skrevet:

  • aa → å, oe → ø, ae → æ (også med stort begyndelsesbogstav)
  • et o i starten af et ord → ø, så oster finder Øster
  • derudover en stavefejlstolerance, der kan rette et eller to forkerte bogstaver i længere ord
Python#folding-demo
import os
import requests

r = requests.get(
    "https://api.danadresse.dk/autocomplete",
    params={"q": "raadhuspladsen 1", "per_side": 3},
    headers={"X-Api-Key": os.environ["DANADRESSE_API_KEY"]},
    timeout=10,
)
r.raise_for_status()
for forslag in r.json():
    print(forslag["forslagstekst"])

Foldningen findes i /autocomplete. Filtrene på /adresser og /adgangsadresser (vejnavn=, husnr=, postnr=) laver ikke den samme foldning. Skriv navnene med æ, ø og å. Kommer dine data uden æøå, så kør dem gennem /autocomplete eller /datavask/adresser først. Datavaskens parser læser stavemåder som Aabenraa, Åbenrå og Kobenhavn og matcher dem med det officielle navn. Se Ingen resultater?

Næste skridt

Relaterede guides

Markdown-kilde Fejl i guiden? Skriv til os API-reference (Swagger)

Prøv det med en gratis nøgle

2 000 kald/måned på gratisplanen. Intet kreditkort.

Opret konto →