Konstrukce schémat pro zajištění jedinečnosti hodnot a referenční integrity

xs:key
definice údajů, které se v dokumentu musí vyskytovat a být unikátní
xs:unique
definice údajů, které musí být unikátní
xs:keyref
referenční integrita definovaná jako odkaz na údaje definované pomocí xs:key nebo xs:unique

Umístění xs:key/xs:unique/xs:keyref

Klíč „vidí“ jen ten element a jeho potomky, uvnitř kterého je uveden. Uvádí se uvnitř xs:element, nikoliv uvnitř xs:complexType.

Definice klíče

xs:selector
XPath vzor, který vybere elementy/atributy, pro které má být zaručena unikátnost.
xs:field
Definice položek (může jich být více), které se použijí při porovnávání klíčů/odkazů na klíče.

Samostatná práce na cvičení

  1. Nahrajte si ukázkové dokumenty a schéma.

  2. Schéma objednavka.xsd rozšiřte tak, aby v dokumentu objednavka.xml provádělo následující kontroly:

    • Dovolena je pouze jedna adresa s danou hodnotou atributu typ.

    • Dovolena je pouze jedna objednávka/doprava s danou hodnotou elementu doprava.

    • V objednávce nejsou dvě položky se stejným kódem.

    • Hodnota elementu doprava uvedená v položka/doprava se musí rovnat některé z hodnot objednávka/doprava.

  3. Vaše schéma zkopírujte do nového souboru a upravte jej tak, aby schéma i v něm obsažené kontroly fungovaly i pro dokument objednavka-ns.xml, který má elementy ve jmenném prostoru.

  4. Nově vytvořené schéma připojte k dokumentu pomocí vhodného atributu ze jmenného prostoru http://www.w3.org/2001/XMLSchema-instance

Domácí úkol

Programová validace

  • v mnoha případech chceme validaci provádět automatizovaně uvnitř aplikace

  • většina jazyků nabízí API pro načítání a validování XML

Příklad 1. Validace XML oproti schématu v PHP

<?php
// nastavení vlastní obsluhy chyb
libxml_use_internal_errors(true);

// načtení dokumentu k validaci
$doc = new DOMDocument();
$doc->load("dokument.xml", LIBXML_NOENT|LIBXML_DTDLOAD|LIBXML_DTDATTR);

// validace dokumentu
if (!@$doc->schemaValidate("schema.xsd"))
{
  echo "Dokument není validní:\n";

  // zjištění všech chyb
  $errors = libxml_get_errors();

  // postupné zpracování všech chyb
  foreach ($errors as $error)
  {
    // u každé chyby vypíšeme jméno souboru, řádek, sloupec a chybové hlášení
    echo $error->file . ":" . $error->line . ":" . $error->column . ":" . $error->message . "\n";
  }
  
  // vyčištění chyb
  libxml_clear_errors();
  exit;
}
else
{
  echo "Dokument je validní oproti W3C XML schématu.";
}
?>

Příklad 2. Validace XML oproti schématu v Javě

import java.io.File;
import java.io.IOException;

import javax.xml.XMLConstants;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import org.xml.sax.SAXException;

public class Validace
{

  public static void main(String[] args) 
  {
    try
    {
      // vytvoření továrny, která umí vytvářet objekty odpovídající WXS schématům
      SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
  
      // načtení WXS schématu ze souboru a uložení do objektu
      Source schemaFile = new StreamSource(new File("schema.xsd"));
      Schema schema = factory.newSchema(schemaFile);
  
      // vytvoření validátoru ze schématu
      Validator validator = schema.newValidator();
      
      // pokus o validaci
      validator.validate(new StreamSource(new File("dokument.xml")));

      System.out.println("Dokument je validní.");
    }
    catch (SAXException e)
    {
      System.out.println("Chyba při validaci: " + e.getMessage());
    }
    catch (IOException e)
    {
      System.out.println("Chyba při načítání: " + e.getMessage());
    }

  }
}

Úkol:

  • Napište XML schéma pro kontrolu XML popisu kurzů na Washington State University (soubor data.zip).

  • Schéma musí implementovat minimálně tato omezení:

    • kurz musí mít instruktora;

    • na kurz musí být zapsáno nejméně pět studentů (enrolled ≥ 5);

    • kurz musí mít budovu a místnost;

    • kurz musí mít den, začátek a konec.

  • Další body získáte, pokud se vám podaří kontrolovat i následující omezení:

    • na kurz nesmí být zapsáno více studentů, než je limit (enrolled ≤ limit);

    • kurz nesmí končit dříve než začíná;

    • kurz musí trvat alespoň hodinu;

    • kurz musí mít počet kreditů.

  • Napište program, který automaticky zkontroluje všechny kurzy a vypíše přehled o počtu validních XML dokumentů. Výstup bude formou dokumentu XML vyhovujícímu schématu bulkvalidationresult.xsd.