Tegnsett
Når programvare skal behandle et tegn innebærer det flere ting. Programmet må få tak i riktig tegnebeskrivelse slik at driveren som framstiller tegnet på det aktuell mediet (skjerm eller skriver) viser rett tegn på rett sted. Programmet må dessuten ofte tolke tegnet inn i en sekvens slik at sortering og sammenligninger blir riktig.
Vi starter med å ha en nettleser som ramme og konsentrerer oss om framstillingen.
Programbiblioteker for handtering av XML tar hensyn til ønsket om generell kodebeskrivelse og vi kan angi hvordan fila er kodet i den første linja i en XML-fil:
<?xml version="1.0" encoding="ISO-8859-1"?>
eller
<?xml version="1.0" encoding="UTF-8"?>
I "gamle" HTML-filer skriver vi f.eks.:
<meta HTTP-EQUIV="Content-Type" content="text/html; charset=ISO-8859-1">
og i HTML5-filer skriver vi f.eks.:
<meta charset=UTF-8">
Vi har sagt at fila er kodet i henhold til ISO-standard 8859/1, også kalt Latin-1, elelr 8-bits unicode UTF-8.
Tradisjonelt tenker vi slik at et tegn er 8-bit. Maskinutstyr og media er tradisjonelt organisert slik at 8 bit, en BYTE, er den enheten vi forholder oss til. Det betyr at vi kan lagre 28=256 forskjellige tegn i en slik BYTE. Disse 8-bitene har opp gjennom databehandlingens historie blitt brukt på forskjellige måte. IBM hadde i gamle dager en koding som de kalte EBCDIC som brukte alle 8 bitene. Den standarden som har hengt med lengst og som vi tar som utgangspunkt i noen resonnementer nedenfor er ASCII.
ASCII
American Standard Code for Information Interchange
ASCII bruker 7 bit og kan følgelig kode 27=128 tegn. Dette er tilstrekkelig til å dekke det engelske alfabetet, minuskler (abc..z) og versaler (AB..Z), sifrene (0123456789), en rekke spesialtegn (+-,.:), en del tegn som ikke skrives men som har betydning for hvordan en tekststreng skal framstilles (linjeskift, tabulator etc), samt en del spesielle koder som er anvendbare i datakommunikasjon. Et ASCII-tegn bruker altså bare 7 av de 8 tilgjengelige bitene i den plassen som er avsatt til å representere et tegn, det første bitet er alltid 0.
Den komplette ASCII-tabellen finner du her [1]
Utvidet ASCII
Hva så når vi har behov for å skrive f.eks. våre spesielle tegn: øæåÆØÅ ? En løsning er å utvide ASCII-tabellen ved å ta i bruk den første biten, som er 0 i standard ASCII. Det gir oss mulighet til å kode 27=128 tegn til, altså tilsammen 256 tegn. Blandt disse ekstra tegnene kan vi kode våre spesielle tegn. Et eksempel på en slik utvidet ASCII-tabell er den som kalles Latin-1 og som er standardisert som ISO-standard 8859/1.
Latin 1 dekker de fleste vesteuropeiske språk, som fransk, spansk, katalansk, baskisk, prtugisisk, italiensk, albansk, nederlandsk, tysk, dansk, svensk, norsk, finsk, færøyisk, islandsk, irsk , skotsk, engelsk. Det dekker også afrikaan og svahili. Det betyr altså at det dekker det amerikanske kontinentet, Australia, Vest Europa og deler av Afrika.
Det finnes andre slike utvidede ASCII-tabeller som dekker andre språkområder. En nettleser som har tilgang til disse utvidede ASCII-tabellene kan altså framstille forskjellige tegnsett.
Unicode
De forskjellige variantene av utvidet ascii er ikke en god og tilstrekkelig generell løsning. Vi kan finne opp den ene variantene etter den andre, men det er tungvindt og vi vil finne språk som ikke får plass innen de rammene som settes av 256 samtidige tegn.
Løsningen på dette er Unicode, en tegnkoding som dekker alle behov. Den vanlige er UTF-8. Det vil si en tegnkoding som tar utgangspunkt i et 8-bits system som kan utvides. Et tegn i UTF-8 kan legge beslag på 1,2,3 eller 4 bytes. Denne løsningen er valgt for å spare plass. De hyppigst forekommende tegnene i verdens tekstmasse (ascii) er beskrevet med 1 byte.
Alternativet var at vi valgte en koding som alltid tok n-bytes, der n >1. Hvis vi f.eks. valgte n=2 ville vi ha et tegnsett med muligheter for 216 tegn. 216=65536 er et ganske stort tall og vi ville trolig dekke de fleste nødvendige, samtidige, tegn. Det vil så vidt jeg vet dekke det kinesiske alfabetet, der de mest omfattende samlingene av ord inneholder 40- til 50 000 tegn. En slik løsning ville imidlertid bety at den (store) delen av verdens teksmateriale som lar seg beskrive med med Latin-1 ville ta dobbelt så stor plass som den gjør idag. Løsningen med n=2 er kjent som UTF-16. Du kan lage en fil i ISO-8859-1 (Latin-1) og be f.eks. XMLSpy oversette den til UTF-16. Da vil du set at den blir dobbelt så stor.
UTF-8 er organisert slik at enkelte tegn er reserverte for å angi ekspansjon av koden. Det vil si at dersom et slik utvidelsestegn opptrer i en sekvens så skal programmet som leser tolke etterfølgende byte som del av tegnbeskrivelsen.
BOM
Paradokset er at det i teorien er umulig for et program, f.eks. en netteleser eller en editor, å vite vilket tegnsett som er brukt i en fil. En byte er en byte og hvordan den skal tolkes er ikke gitt. BOM [2] er forsøk på løse dette for unicode-filer. BOM betyr at man legger inn tre tegn i starten av fila som signaliserer koden (Byte Order Mark). Dette er i mange sammenhenger ganske lurt men det forutsetter at de programmene som skal behandle slike filer vet om det, ellers vil de tolke BOM-tegnene som deler av innholdet. Det kan se slik ut:  for utf-8.
For XML-filer er det utviklet algoritmer som treffer beslutningen om koding basert på tolkning av den første linja:
<?xml version="1.0" encoding="utf-8"?>
Denne teksten er så stabil og lik for alle XML-filer at den er tolkbar med tanke på å finne verdien til encoding-attributten, uavhengig av faktisk encoding. Dette forutsetter at det ikke ligger noe i fila, f.eks. BOM, foran linja over. Dersom det gjør det er feilmeldingen er typisk av denne typen: "content is not allowed in prolog" eller "XML Parsing Error: no element found". Vi kan altså sitte i en editor i god tro og editere en fil som er lagret som utf-8 med BOM. Hvis editoren er BOM-følsom vil vi ikke oppdage dette før vi eksponerer fila som XML-fil for et annet program som ikke er BOM-følsomt, f.eks. en nettleser.
Den feilen de fleste av oss gjør er å skrive i en editor som produserer encoding som er forskjellig fra det vi tror, og som vi enten skriver inn i XML-headeren eller i metataggen i en HTML-fil. Det hjelper ikke om vi skriver:
<?xml version="1.0" encoding="utf-8"?>
eller
<!DOCTYPE HTML> <head> <meta charset="UTF-8"/> </head> ....
Dersom den faktiske encodingen er ISO-8859.