Hyvinmuodostuneisuusrajoitukset


'<'-merkki ei ole sallittu määritteen arvossa (No < in Attribute Values)

Selitys: Määritteelle annettavassa arvossa ei saa esiintyä '<'-merkkiä. Merkki on kielletty niin suoraan annettuna kuin entiteetin korvaavassa tekstissäkin. '<'-merkin sijaan määritteen arvossa on käytettävä '&lt;'-entiteettiä.

Tärkein syy tähän rajoitukseen on rajoittaa '<'-merkin käyttö tunnisteen aloitusmerkiksi, jolloin XML-dokumenttia käsittelevien sovellusten tekeminen on hivenen helpompaa. Lisävaikutuksena mm. kirjoitusvirheet voivat paljastua helpommin (tosin hyöty on yleisesti aika vaatimaton ja XML-editoreja käytettäessä täysin olematon).

Esimerkkejä: Ensimmäisessä esimerkissä on käytetty '<'-merkin sijasta '&lt;'-viittausta. Toinen esimerkki on osoitus, miten pienet kirjoitusvirheet paljastuvat helpommin tämän rajoituksen avulla.

<tiivistelma pituus="&lt; 60">
    Esimerkki on kirjoitettu puhtaasta kirjoittamisen ilosta. 
    Esimerkki on virheetöntä XML:ää.
</tiivistelma>
<tiivistelma pituus="&lt; 60>
	Esimerkki pienestä kirjoitusvirheestä, joka sattuu aika helposti
	kirjoitettaessa XML-dokumenttia tavallisella tekstieditorilla.
</tiivistelma>

Jälkimmäisessä esimerkissä on määritteen arvosta unohtunut '"'-merkki - virhe, joka ainakin itselleni on sattunut useammankin kerran. Jäsennin huomauttaa virheestä 'tiivistelma'-elementin lopputunnisteen kohdalla, koska se rikkoo rajoitusta vastaan.

Koskee sääntöjä: Attribute (41), DefaultDecl (60)

Ei entiteettiviittauksia itseensä (No Recursion)

Selitys: Jäsennetty entiteetti - oli se sitten parametri- tai yleisentiteetti - ei saa sisältää suoria tai epäsuoria viittauksia itseensä. Mikäli entiteetti voisi viitata itseensä, jäisi XML-jäsennin ikuiseen silmukkaan yrittäessään jäsentää viittauksia.

Esimerkkejä:

<!ENTITY toisto        "toistoa &toisto;">
<!ENTITY ikuinenTotuus "Historia on vain saman vanhan &toisto;.">

Edellinen esimerkki rikkoo rajoituksen, sillä 'toisto'-entiteetti sisältää suoran viittauksen itseensä. Korvattaessa entiteetit viittausten paikalle on lopputuloksen alku tämännäköinen: "Historia on vain saman vanhan toistoa toistoa toistoa toistoa toistoa toistoa ..."

Toisessa esimerkissä on rakennettu rajoituksen vastainen epäsuora viittaus 'rakenne' ja 'alirakenne' -entiteettien välillä:

<!ENTITY rakenne    "luvun jälkeen tulee aliluku &alirakenne;">
<!ENTITY alirakenne "ja ali&rakenne;">
<!ENTITY kirja      "Kirjan rakenne on: &rakenne;">

Koskee sääntöjä: EntityRef (68), PEReference (69)

Entiteetin oltava esitelty (Entity Declared)

Selitys: Rajoituksen ajatuksena on listata säännöt, joiden perusteella validoimaton jäsennin voi olla varma, että se on lukenut kaikki entiteettiesittelyt. Perussääntönä voidaan pitää entiteetin esittelemistä ennen sen käyttöä, oli kyseessä sitten parametri- tai yleisentiteetti. Entiteettiviittauksessa mainitun nimen on vastattava jotain entiteetin esittelyä kun kyseessä on:

Poikkeuksena tästä ovat oletusarvoisesti määritellyt amp, lt, gt, apos ja quot -entiteetit.

Dokumentissa, jossa on rakennemäärittelyn ulkoinen osajoukko tai ulkoisia parametrientiteettejä, kuuluu tämä rajoitus hyvinmuodostuneisuusrajoituksiin vain kun riippumattomuusesittelyssä on annettu arvo 'yes' (eli 'standalone="yes"'). Tämä siksi, että validoimattoman jäsentimen ei ole pakko lukea dokumentin ulkopuolisia esittelyitä tai entiteettejä.

Katso myös vastaavan nimistä validisuusrajoitusta, joka täydentää tätä rajoitusta.

Esimerkkejä: Seuraavassa on esimerkki oikeassa järjestyksessä kirjoitetuista entiteettiesittelyistä:

    <!ENTITY hahmonNimi1 "Matti Mainio">
    <!ENTITY hahmonNimi2 "Jussi Juonio">
    <!ENTITY sarjakuva   "&hahmonNimi1; ja &hahmonNimi2;">
    <!ENTITY mainoslause "Uusi huippusarjakuva: &sarjakuva;!">

Seuraavassa katkelmassa on useampikin virhe:

<?xml version="1.0" standalone="yes">
    <DOCTYPE lehtimainos [
    <!ENTITY sarjakuva   "&hahmonNimi1; ja &hahmonNimi2;">
    <!ENTITY hahmonNimi1 "Matti Mainio">
    <!ENTITY hahmonNimi2 "Jussi Juonio">
    <!ENTITY mainoslause "Uusi huippusarjakuva: &sarjakuva;, tekijänä &taiteilijanNimi;!">
]>
<lehtimainos>
   &mainoslause; Nyt vain &hinta;
</lehtimainos>

Esimerkin ensimmäinen virhe on väärä esittelyjärjestys: 'hahmonNimi1' ja 'hahmonNimi2' pitäisi esitellä ennen 'sarjakuva'-entiteettiä, jossa kyseisiä viittauksia käytetään. Toinen virhe on viittaus 'taiteilijanNimi'-entiteettiin, sillä riippumattomuusesittelyssä on annettu arvo 'yes', jolloin merkkausesittelyjä ei saa olla dokumenttientiteetin ulkopuolella. Kolmas virhe on 'lehtimainos'-elementin sisällä oleva viittaus 'hinta'-entiteettiin, jota ei ole esitelty lainkaan.

Koskee sääntöä: EntityRef (68)

Lopputunnisteen vastattava alkutunnistetta (Element Type Match)

Selitys: Elementin lopputunnisteessa olevan elementtityypin nimen on oltava sama kuin alkutunnisteessa.

Esimerkkejä: Lyhyt esimerkki rajoituksen rikkovasta elementistä, joka alkaa 'kirja'-tunnisteella ja päättyy 'opus'-tunnisteeseen:

<kirja>
    Kirja, jolla on alku, mutta ei soveliasta loppua.
</opus>

Seuraavassa sama esimerkki korjattuna:

<kirja>
    Kirja, jolla on alku, mutta ei soveliasta loppua.
</kirja>

Koskee sääntöä: element (39)

Määrite saa esiintyä elementin tunnisteessa vain kerran (Unique Att Spec)

Selitys: Määritteellä ei saa olla kahta tai useampaa ilmentymää saman elementin alkutunnisteessa tai tyhjän elementin tunnisteessa. Tällä tavalla voidaan varmistaa, että määrite saa yksikäsitteisen arvon.

Esimerkki:

<kirja tekija="Kaija Kirjailija" tekija="Keijo Kirjailija">
    <nimi>Väärät määritelmät</nimi>
</kirja>

Esimerkissä esiintyi kaksi kertaa 'tekija'-määrite, mikä rikkoo rajoitusta vastaan. Vaikka esimerkki saattaa tuntua muuten järkevältä ja käyttökelpoiselta, on tällaisessa tilanteessa yleensä syytä (ja rajoituksen mukaan myös pakollista) käyttää elementtejä määritteiden sijaan.

Koskee sääntöjä: STag (40), EmptyElemTag (44)

Määritteiden arvoissa ei saa olla viitauksia ulkoisiin entiteettihin (No External Entity References)

Selitys: Määritteiden arvoissa ei saa olla suoria tai epäsuoria viittauksia ulkoisiin entiteetteihin. Ilman tätä rajoitusta määritteiden arvoissa voitaisiin mm. käyttää dokumentin merkistöstä poikkeavia merkistöjä, sillä sisältöesittelyn avulla XML mahdollistaa eri merkistöjen käytön ulkoisissa entiteeteissä. Useiden merkistöjen salliminen todennäköisesti vaikeuttaisi jäsentimien toimintaa ja vähentäisi niiden tehokkuutta, mistä syystä rajoitus on olemassa.

Esimerkki:

<?xml version="1.0" ?>
<DOCTYPE kirjasto [
    <!ENTITY  XML-kirjat SYSTEM "xml.txt"> 
    <!ELEMENT kirjasto   (kirja+)>
    <!ELEMENT kirja      (#PCDATA)>
    <!ATTLIST kirja
              sijainti   CDATA #REQUIRED>
]>
<kirjasto>
    <kirja sijainti="&XML-kirjat;">
        Uusi opas XML:n maailmaan.
    </kirja>
    <kirja sijainti="&XML-kirjat;">
        XML ja siihen liittyvät määritykset nelivärikuvina.
    </kirja>
</kirjasto>

Esimerkissä rikotaan rajoitusta vastaan, sillä 'XML-kirjat'-määritellään ulkoiseksi entiteetiksi, mutta siitä huolimatta sitä käytetään määritteiden arvossa.

Koskee sääntöä: Attribute (41)

Parametrientiteettien käyttö rakennemäärittelyn sisäisessä osajoukossa (PEs in Internal Subset)

Selitys: Rakennemäärittelyn sisäisessä osajoukossa (siis rakenne-esittelyssä '[' ja ']' -merkkien välissä) viittaukset parametrientiteetteihin ovat sallittuja vain kohdissa, joissa kokonaiset merkkausesittelytkin ovat sallittuja. Parametrientiteettiviittauksia ei siis saa olla esimerkiksi esittelyjen sisällä.

Tämä rajoitus ei kuitenkaan koske ulkoisia parametrientiteettejä tai rakennemäärittelyn ulkoista osajoukkoa. Niissä voidaan käyttää myös jäljempänä olevan esimerkin esittelyä, joka sisäisessä osajoukossa on rajoituksen vastainen.

Rajoituksen tarkoituksena on helpottaa ja yksinkertaistaa validoimattomien jäsentimien toimintaa.

Esimerkkejä:

<!DOCTYPE kirjasto [
   <!ENTITY  % aloitus "omistaja">
   <!ELEMENT kirjasto  (%aloitus;, kirja+)>
   <!ELEMENT kirja     (%aloitus;, kuvaus)>
   <!ELEMENT omistaja  (#PCDATA)>
   <!ELEMENT kuvaus    (#PCDATA)>
]>

Tapa, jolla edellisessä esimerkissä käytetään parametrientiteettiä, on hyvin yleinen SGML-rakennemäärittelyissä. XML:ssä se on kuitenkin kielletty.

Seuraavassa esimerkissä käytetään 'aloitus'-entiteettiä sallitulla - joskin tässä tapauksessa täysin keinotekoisella ja turhalla - tavalla:

<!DOCTYPE kirjasto [
    <!ENTITY  % aloitus "<!ELEMENT omistaja (#PCDATA)>">
    <!ELEMENT kirjasto  (omistaja, kirja+)>
    <!ELEMENT kirja     (omistaja, kuvaus)>
    %aloitus;
    <!ELEMENT kuvaus    (#PCDATA)>
]>

Koskee sääntöä: markupdecl (29)

Viittaus jäsennettyyn entiteettiin (Parsed Entity)

Selitys: Entiteettiviittauksen on aina oltava jäsennettyyn entiteettiin. Jäsentämättömiä entiteettejä saa käyttää vain määritteissä, jotka ovat ENTITY tai ENTITIES -tyyppisiä. Käytännössä rajoituksen vuoksi elementtien sisältöön tai rakennemäärittelyyn saa sijoittaa ainoastaan entiteettejä, joiden sisältönä on tekstiä tai merkkausta. Formaatteja, joita XML-määrittelyn säännöt eivät koske, ei voi sijoittaa suoraan dokumenttiin - niiden ainoa sijoituspaikka on ENTITY tai ENTITIES -tyyppisten määritteiden arvona.

Esimerkkejä: Ensimmäisessä esimerkissä kuvataan jäsentämättömän entiteetin sallittu käyttötapa ja toisessa kielletty.

<!DOCTYPE mainos [
    <!NOTATION gif         PUBLIC "-//CompuServe Information Services, Inc.//NOTATION Graphics Interchange Format (GIF)//EN">
    <!ENTITY   tekijanKuva SYSTEM "mina.gif" NDATA gif>
    <!ELEMENT  mainos      (#PCDATA)>
    <!ATTLIST  mainos
               tekija      ENTITY #IMPLIED>
]
<mainos tekija="tekijanKuva">
    Uusinta uutta!
<mainos>
<!DOCTYPE mainos [
    <!NOTATION gif        PUBLIC "-//CompuServe Information Services, Inc.//NOTATION Graphics Interchange Format (GIF)//EN">
    <!ENTITY   firmanLogo SYSTEM "logo.gif" NDATA gif>
    <!ELEMENT  mainos     (#PCDATA)>
]
<mainos>
    Uusinta uutta! Meiltä: &firmanLogo;
<mainos>

Jälkimmäisessä esimerkissä käytetään 'firmanLogo'-entiteettiä elementin sisällössä, vaikka se on jäsentämätön entiteetti.

Koskee sääntöä: EntityRef (68)

Viittaukset parametrientiteetteihin sallittuja vain rakennemäärittelyssä (In DTD)

Selitys: Viittaukset parametrientiteetteihin ovat sallittuja vain rakennemäärittelyn sisällä. Parametrientiteettien tarkoituksena on säilöä rakennemäärittelyn osia uudelleenkäytettäväksi, jolloin niillä ei ole käyttöä dokumentti-ilmentymässä.

Parametrientiteettiin viittaaminen dokumentti-ilmentymässä on sallittua. Tällöin viitteellä ei kuitenkaan ole erikoismerkitystä, kuten esimerkiksi muilla entiteettiviitteillä, vaan viittausta käsitellään tavallisena merkkijonona.

Esimerkki:

<kirja>
    <nimi>Kaikki XML:stä</nimi>
    <tiivistelma>
        Tämä kirja kertoo kaiken XML:stä. Myös sen mitä tarkoittaa kun
        rakennemäärittelyssä esitellään elementti seuraavasti: 
        %kirjanDTD;
    </tiivistelma>
</kirja>

Esimerkissä dokumentti-ilmentymässä esiintynyt '%kirjanDTD;' on tavallinen merkkijono eikä viittaus 'kirjanDTD'-parametrientiteettiin.

Koskee sääntöä: PEReference (69)

Viittaukset vain sallittuihin merkkeihin (Legal Character)

Selitys: Merkki, johon merkkiviittauksessa viitataan, on oltava Char-säännön mukainen. Tämä on luonnollinen vaatimus, mikäli XML-dokumentti halutaan säilyttää sääntöjen mukaisena merkin sijoituksen jälkeenkin.

Esimerkki: Koska Char-sääntö ei salli ihan kaikkia Unicoden merkkejä, on esimerkin ensimmäinen merkkiviite kielletty:

<kirja>
    <nimi>Kaikki maailman merkeistä</nimi>
	<tiivistelma>
	    Kirja kuvaa kaikki maailman merkit, jopa sellaisetkin
	    harvinaisuudet kuten &#xFFFF; ja &#36; 
	</tiivistelma>
</kirja>

Koskee sääntöä: CharRef (66)


Sivua on edellisen kerran päivitetty: 07.02.2000.
Kommentteja voi lähettää Henri Ruinille osoitteeseen ruini@cs.helsinki.fi.