Validació XML amb DTD

Introducció

  • Validació de documents:

Què és el DTD?

El DTD (Document Type Definitions) és una forma de definir l'estructura i les etiquetes vàlides en un document XML.

  • És la forma de definició d'esquemes que va sortir primer.
    • Va sorgir en el temps del SGML

L'objectiu principal dels DTD és permetre validar les estructures dels documents XML.

  • El document XML es comprovarà amb l'esquema DTD.

Hi poden haver documents ben formats que no siguin vàlids.

El DTD pot ser compartit entre organitzacions o, fins i tot, definir-lo com a estàndard públic.

  • Això permetrà conèixer les especificacions que defineixen un vocabulari concret.

Limitacions del DTD

  • El DTD no és un llenguatge XML: Això obliga a aprendre dos llenguatges en comptes d'un!
  • Pot ser que no puguem fer-hi tot el que ens faci falta:

    • DTD no pot fer comprovacions del contingut de dades:
    <data>.</data>
    
    • No pot comprovar que és una data correcte.
  • Podria fer falta definir restriccions en el document però amb DTD no es pot:
    • Per exemple una data entre 1970 i 2032.

Encara hi ha molts documents XML que es validen amb DTD (tot i que té les seves limitacions).

Validació

Amb xmllint ho podem fer amb valid:

$ xmllint --noout --valid exercici.xml

També es pot fer amb el programa XML Copy Editor, etc...

image

O amb validadors online:

El llenguatge DTD

Definició del DTD

Definició de DTD Interna

Es poden incorporar DTD dins dels documents XML:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE process [
<!ELEMENT adress (#PCDATA)>
<!ELEMENT process (adress)>
]>
<process>
    <adress>http://www.boscdelacoma.cat</adress>
</process>
  • Tot i que es pot fer és millor fer-los externs.
  • Definir-los externament permet compartir-los més fàcilment i a més:

Separa les dades de la estructura.

Definició de DTD Externa

Per definir un DTD extern que s'utilitza fent servir l'etiqueta DOCTYPE dins del document XML:

  • Es poden definir DOCTYPES d'Internet:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE alumnes SYSTEM "http://www.boscdelacoma.cat/alumnes.dtd">
<alumnes>
    <persona>
        <nom>Pere</nom>
        <cognom>Pi</cognom>
    </persona>
</alumnes>
  • O en fitxers locals:
<!DOCTYPE alumnes SYSTEM "alumnes.dtd">

image

I després només hem de crear el DTD extern en el lloc adequat:

<!ELEMENT nom (#PCDATA)>
<!ELEMENT cognom (#PCDATA)>
<!ELEMENT persona (nom,cognom)>

Elements

S'han de definir tots els elements que formen el document:

<!ELEMENT nom (contingut) >

En el contingut és on definirem completament l'estructura del document XML:

  • Si hi ha dades
  • Si conté altres etiquetes
  • Etc.

image

Elements genèrics

Si tenim elements que poden tenir qualsevol cosa a dins els podem definir amb ANY

Aquests elements podràn contenir altres etiquetes o bé dades.

Per exemple:


<persona>Pere Pi</persona>
<persona>
     <nom>Marta</nom>
     <cognom>Mata</cognom>
</persona>

Podem definir <persona>:

<!ELEMENT persona ANY>

Entrada de text: #PCDATA

Un #PCDATA indica que l'element que estem definint només pot tenir dades a dins.

Per exemple:

<nom>Pere</nom>
<cognom>Pi</cognom>

Es definiria el DTD amb:

<!ELEMENT nom (#PCDATA)>
<!ELEMENT cognom (#PCDATA)>

Elements sense dades

Si tenim elements que no tenen contingut els podem definir amb EMPTY.

Per exemple:

XML

<persona>
    <nom>Pere</nom>
    <cognom>Pi</cognom>
    <real />
</persona>

<persona>
    <nom>Marta</nom>
    <cognom>Mata</cognom>
</persona>

DTD

<!ELEMENT real EMPTY>

Elements fills

El més normal és que una etiqueta en contingui d'altres.

Els elements que contenen altres etiquetes es defineixen amb el nom dels elements fills dins de parèntesis ().

<persona>
    <nom>Pere</nom>
    <cognom>Pi</cognom>
</persona>

Els definim posant les etiquetes que pot contenir:

DTD

<!ELEMENT nom (#PCDATA)>
<!ELEMENT cognom (#PCDATA)>
<!ELEMENT persona (nom,cognom)>

ATENCIÓ: Els elements fills han d'aparèixer en el XML en la mateixa seqüència (ordre) que en el DTD.

Es poden definir elements recursius:

<!ELEMENT node (fulla | node, node)>
  • Però s'ha d'anar amb compte perquè podem generar un problema molt més gran.
  • Definir elements que no s'acabin mai i que per tant no puguin ser validats.
<!ELEMENT node (node, node)>
  • O sigui que es poden fer però sempre s'han de tractar amb cura

Modificadors dels elements fills

Podem especificar quantes instàncies dels elements fills hi poden haver en un element.

  • ?: Indica que l'element hi pot ser o no.
  • *: Indica que l'element hi pot ser un número indeterminat de vegades o no ser-hi.
  • +: Indica que l'element hi ha de ser una vegada o més.

Per exemple:

DTD

<!ELEMENT persona (nom, cognom+)>

XML

<persona>
    <nom>Pere</nom>
    <cognom>Pi</cognom>
    <cognom>Pujol</cognom>
</persona>
<persona>
    <nom>Marta</nom>
    <cognom>Mata</cognom>
</persona>

Operador d'elecció

També tenim un operador que ens permet posar alternatives |

<!ELEMENT titol (president|treballador)>

Ens permetria fer:

<titol>
    <president>Pere Pi</president>
</titol>

O bé:

<titol>
     <treballador>Pere Pi</treballador>
</titol>

Parèntesis

Evidentment podem fer tantes agrupacions de parèntesi com ens facin falta.

Exemples:

<!ELEMENT cercle (centre, (radi | diametre))>
  • Centre i radi o bé centre i diàmetre
<!ELEMENT comic (cognom | ( nom,(inicials, cognom) | cognom ))>
  • cognom o nom+inicials+cognom o nom+cognom
<!ELEMENT paragraf (#PCDATA | nom | professio | marca | data )* >

Limitacions

No es poden posar etiquetes i #PCDATA que no siguin "contingut barrejat".

Això és erroni:

<!ELEMENT exercici (#PCDATA, apartat*)>

Tampoc podem duplicar definicions:

<!ELEMENT exercici (#PCDATA)  >
<!ELEMENT exercici (apartat*) >

O sigui que hem de fer això (tot i que pot no ser el que volem)

<!ELEMENT exercici (#PCDATA, apartat)*>

Expressions deterministes

Una altra de les limitacions és que obliga a que les expressions han de ser deterministes.

Això vol dir que no es pot fer això:

<!ELEMENT terrestre((persona,home)|(persona,dona))>

Això és perquè el processador al rebre 'persona' no pot saber quina és l'expressió que estem fent.

Ho hem d'escriure:

<!ELEMENT terrestre(persona,(home|dona))>

El mateix ens passarà si fem servir modificadors:

Per exemple perquè surti en l'ordre que vulguem autor i títol:

<!ELEMENT llibre((autor?,titol?)|(titol?,autor?))>

Després de rebre autor en quina expressió estem? I si rebem títol? Ho hauríem d'escriure d'aquesta forma:

<!ELEMENT llibre((autor,titol?)|(titol,autor?)|EMPTY)>

Ara no queda cap dubte de on som al rebre una etiqueta

Atributs

  • Ens pot interessar limitar quins atributs pot contenir una etiqueta.
  • No es poden fer atributs genèrics s'han de definir en cada element.
  • Els atributs es defineixen amb ATTLIST

image

Atributs dels atributs

Un aspecte curiós és que els atributs tenen atributs que permeten definir com s'usaran.

  • IMPLIED: L'atribut és opcional. Cada instància de l'element pot o no pot donar-li valor.
  • REQUIRED: L'atribut és obligatori. Ha d'existir!
  • FIXED: L'atribut és constant i inmutable. S'ha d'especificar per força ja que és permanent.
  • DEFAULT: L'atribut ja té un valor per defecte. Si no se n'hi posa cap un programa ha d'assumir aquest valor.

Per exemple:

<!ATTLIST equip posicio ID #REQUIRED>
<!ATTLIST nom dni NMTOKEN #IMPLIED>
<!ATTLIST document versio CDATA #FIXED "1.0">
  • L'etiqueta equip ha de tenir l'atribut "posicio" obligatòriament
  • El dni associat al nom és opcional
  • La versió del document és "1.0" i no es pot canviar

Tipus de dades atributs

Existeixen diferents tipus de dades que es poden fer servir com a tipus d'atributs.

Tipus Significat
CDATA Pot contenir qualsevol cadena de caràcters acceptable. Es pot fer servir per preus, URL, emails, etc...
Enumeracions Posem una llista de valors textuals dins de la declaració de l'atribut
ID Un atribut pot fer-se servir com identificador d'un element. Aquest atribut ha de ser únic en el document
IDREF o IDREFS Referències a un ID. El seu valor s'ha de correspondre amb un identificador d'element existent
ENTITY o ENTITIES Les entitats permeten definir constants pel document. Així doncs l'atribut ha de ser una entitat
NMTOKEN NMTOKENS Especifiquen els caràcters permesos per XML. O sigui que no s'hi permeten espais
NOTATION Permet que l'atribut sigui d'una notació anteriorment declarada

CDATA i enumeracions

Els atributs de tipus CDATA permeten la entrada de text de qualsevol tipus.

<!ATTLIST empresa nom CDATA #REQUIRED>

Ens permetria definir coses com:

<empresa nom="Microsoft Corporation">
<empresa nom="6tema desastre, SA">

Un cas especial serien les enumeracions:

<!ATTLIST curs inici (setembre|octubre) #IMPLIED>
  • Que permetran que el valor de l'atribut sigui o "setembre" o "octubre" i cap més.

ID

ID serveix per quan els atributs es poden utilitzar com identificadors d'un element dins del document.

  • Els valors no es poden repetir.
  • Els valors han de començar per una lletra o pel caràcter de subratllat.

DTD

<!ATTLIST equip posicio ID #REQUIRED>

XML

<equip posicio="primer">F.C.Barcelona</equip>
<equip posicio="tretzè">Real Madrid C.F.</equip>

IDREF o IDREFS

Es fan servir quan el valor ha de ser una referència a un identificador.

<!ATTLIST recepta id ID #REQUIRED>
<!ATTLIST ingredient ref IDREF #IMPLIED>
<llibrecuina>
    <recepta id="recepta1">Patates fregides</recepta>
    <recepta id="recepta2">Patates bullides</recepta>
    <ingredient ref="recepta1">oli</ingredient>
</llibrecuina>

IDREFS ens permet fer una llista d'ID separades per espais.

<!ATTLIST ingredient refs IDREFS #IMPLIED>
<ingredient refs="recepta1 recepta2">patates</ingredient>

NMTOKEN i NMTOKENS

Els tipus NMTOKEN permeten que especifiquem qualsevol caràcter acceptat per XML.

  • Això implica text sense espais.
  • Com la majoria de vegades el NMTOKENS ens en permet especificar diversos separats per espais
<!ATTLIST home naixement NMTOKEN #IMPLIED>
<!ATTLIST home fills NMTOKENS #IMPLIED>
  • O sigui
<home naixement="1975">Carles Punxatí</home>
<home fills="Maria Pere Albert">Filomenu Pi</home>

NOTATION

Aquest atribut permet associar una aplicació a un tipus d'informació.

<!NOTATION jpg PUBLIC “JPEG">
<!ATTLIST persona foto NOTATION jpg #IMPLIED>

Es pot canviar PUBLIC per SYSTEM per poder definir una aplicació en particular.

Per exemple un tipus MIME

<!NOTATION jpg SYSTEM "image/jpeg">

ENTITY / ENTITIES

Les entitats permeten definir les constants pel document

  • Els atributs poden fer referència a constants
<!ATTLIST A a ENTITY #IMPLIED>
<!ATTLIST A b ENTITIES #IMPLIED>

Podem definir les nostres entitats:

<!ENTITY nom "valor">

I després utilitzar-les en el document

&nom;

Entitats predefinides i externes

Tenim entitats que ens permeten escriure caràcters amb el seu valor hexadecimal:

&#41;
  • I les ja conegudes
&lt; &gt; &amp; &apos;

results matching ""

    No results matching ""