Æ, ø 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.
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 ser | Det 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'en | R%C3%A5dhuspladsen | Teksten 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:
| Tegn | URL-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:
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:
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 $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 udencharsetsom Latin-1. Brug PowerShell 7, eller læs bytes og dekod dem selv:
$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:
- 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).
- Power Query. Angiv tegnsættet direkte:
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
- 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:
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
oi starten af et ord → ø, såosterfinderØster - derudover en stavefejlstolerance, der kan rette et eller to forkerte bogstaver i længere ord
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)