Upload
morgan-parker
View
230
Download
0
Embed Size (px)
Citation preview
XML pre programátorov
7. víkend s Linuxom
5. – 6. október 2002
Žilina
Stanislav Meduna
ETM Aktiengesellschaft
ObsahObsah
• Čo je to XML
• Základné princípy
• Oblasti využitia
• Príklad dokumentu
• Objektové a udalostné rozhrania
• libxml2
• Príklad parsera
Čo je XMLČo je XML
• EXtensible Markup Language
• Jazyk pre popis informácií
– pre ľudí
– pre programy
• Sám o sebe nerobí vôbec nič
• Je na aplikácii dať dátam význam
ExtensibleExtensible
• XML definuje iba štruktúru
• Žiadne preddefinované značky
• Konkrétne značky sú vecou aplikácie
• Dokonalá rozšíriteľnosť
MarkupMarkup
• Stromová štruktúra
• Značky
– Elementy
– Atribúty
• Obsah (vlastné informácie)
• Entity
LanguageLanguage
• Presne definované pravidlá
– Správna syntax (well-formed)
– Správna štruktúra (valid) - DTD, Xschema
• Možnosť automatickej kontroly
• Súvisiace štandardy
– Namespaces, XSL, XLink, XPointer, ...
Oblasti použitiaOblasti použitia
• Publikovanie dokumentov
• Uchovávanie štruktúrovaných údajov
• Protokoly pre výmenu informácií
(napr. SOAP)
• Dobré pre profesný životopis :-)
Prečo používať XML?Prečo používať XML?
• Formát čitateľný pre človeka aj stroj
• Netreba písať „zase ďalší parser“
• Jednoduché rozširovanie
• Multiplatformný štandard
• Súvisiace štandardy riešia niektoré
obvyklé aplikácie
Definícia typu dokumentuDefinícia typu dokumentu
• Aké elementy existujú
• Aké sú ich atribúty
• Aký je ich povolený obsah
• Kontrola správnosti štruktúry• „Návod“ pre spracovanie• Pomôcka pre čitateľa
Zoznam distribúcií – modelZoznam distribúcií – model
FreeOnly
DistList
DistroPackaging
Vendor Version CodeName Package
File
Name
Version
Release
Free
0..n
0..1 0..1 0..n
0..n
Zoznam distribúcií – DTD (1)Zoznam distribúcií – DTD (1)
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Priklad pre 7. vikend s Linuxom -->
<!ENTITY % bool "true | false">
<!ELEMENT DistList (Distro*)>
<!ELEMENT Distro (Vendor, Version?, CodeName?, Package*)>
<!ATTLIST Distro
FreeOnly (%bool;) "false"
Packaging (rpm|deb|tgz|other|none) "rpm"
>
Zoznam distribúcií – DTD (2)Zoznam distribúcií – DTD (2)
<!ELEMENT Vendor (#PCDATA)><!ELEMENT Version (#PCDATA)><!ELEMENT CodeName (#PCDATA)><!ELEMENT Package (File*)><!ATTLIST Package Name CDATA #REQUIRED Version CDATA #REQUIRED Release CDATA "" Free (%bool;) "true"><!ELEMENT File (#PCDATA)>
Zoznam distribúcií – dokument (1)Zoznam distribúcií – dokument (1)
<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE DistList SYSTEM "distros.dtd"><DistList> <Distro FreeOnly="false" Packaging="rpm">
<Vendor>Red Hat</Vendor> <Version>7.3</Version> <CodeName>Valhalla</CodeName> <Package Name="basesystem" Version="7.0" Release="2"/> <Package Name="redhat-logos" Version="2.5.12" Release="1" Free="false"> <File>/usr/share/pixmaps/redhat/shadowman-32.png</File> </Package> </Distro> <Distro FreeOnly="true" Packaging="deb"> <Vendor>Debian</Vendor> <CodeName>Potato</CodeName> </Distro>
</DistList>
Zoznam distribúcií – dokument (2)Zoznam distribúcií – dokument (2)
...
<Distro FreeOnly="false" Packaging="rpm">
<Vendor>Red Hat</Vendor>
<Version>7.3</Version>
<CodeName>Valhalla</CodeName>
<Package Name="basesystem" Version="7.0" Release="2"/>
<Package Name="redhat-logos" Version="2.5.12" Release="1" Free="false">
<File>/usr/share/pixmaps/redhat/shadowman-32.png</File>
</Package>
</Distro>...
ParseryParsery
• DOM (Document Object Model)– Strom v pamäti– Jednoduchá práca– Potrebuje viac pamäti– Jednoduchá modifikácia a zápis
• SAX (Simple API for XML)– Callbacky do používateľovho kódu– Stavy (a spotreba pamäti) sú vecou používateľa– Zložitejšia práca– Lepšia kontrola
libxml2libxml2
• Linux / Unix / Windows
• MIT licencia
• Obyčajné C
• Objektové aj udalostné rozhranie
• Mnoho pohodlných vlastností
DOMDOM
FreeOnly
Document
DistList
Packaging
Vendor CodeName
Root element
Distro Distro
children
parentnext
prevchildren
properties
next
nextcontent
content
Valhalla
rpm
SAXSAX – – stavový automatstavový automat
DistList
Distro
Vendor
Version CodeName
startElement endElement
Package
Vendor
SAXSAX – callbacky – callbacky
<DistList>
<Distro
FreeOnly="false"
Packaging="rpm"
>
<Vendor>
Red Hat
</Vendor>
startElement("Distro",
{ "FreeOnly", "false",
"Packaging", "rpm", NULL })
startElement("DistList", { NULL })
startElement("Vendor", { NULL })
characters("Red Hat")
endElement("Vendor“)
Libxml2 – DOM parserLibxml2 – DOM parser ( (11))
#include <libxml/parser.h>#include <libxml/tree.h>#include <stdio.h>
int main(int argc, char **argv){ xmlDocPtr doc; xmlNodePtr distro, diEl; xmlAttrPtr attr;
xmlKeepBlanksDefault(0); doc = xmlParseFile("distros.xml"); distro = xmlDocGetRootElement(doc)->children;
Document
DistList
Root El
Distro
children
Libxml2 – DOM parserLibxml2 – DOM parser ( (22))
while (distro) { if (!strcmp(distro->name, "Distro")) { diEl = distro->children; while (diEl) { if (! strcmp(diEl->name, "Vendor") || ! strcmp(diEl->name, "CodeName")) printf("%s ", diEl->children->content); diEl = diEl->next; }
attr = distro->properties; while (attr) { if (! strcmp(attr->name, "Packaging")) printf("%s ", attr->children->content); attr = attr->next; }
} distro = distro->next; printf("\n");} FreeOnly
Vendor
Distro
Distro
next
children
properties
Libxml2 – DOM parserLibxml2 – DOM parser ( (33))
diEl = distro->children; while (diEl) { if (! strcmp(diEl->name, "Vendor") || ! strcmp(diEl->name, "CodeName")) printf("%s ", diEl->children->content); diEl = diEl->next; } attr = distro->properties; while (attr) { if (! strcmp(attr->name, "Packaging")) printf("%s ", attr->children->content); attr = attr->next; }}
Vendor CodeNamenext
FreeOnly Packagingnext
Libxml2 – Libxml2 – SAX parser (1)SAX parser (1)
static enum {
PARSER_START,
PARSER_DISTLIST,
PARSER_DISTRO,
…
} parserState = PARSER_START;
…
Distro
Vendor
Version
static void distStartElement(void *state, const xmlChar *name, const xmlChar **attrs)
{
switch (parserState) {
…
case PARSER_DISTRO:
if (! strcmp(name, "Vendor")) {
parserState = PARSER_VENDOR;
} else if (! strcmp(name, "Version")) {
parserState = PARSER_VERSION;
…
Libxml2 – Libxml2 – SAX parser (2)SAX parser (2)
Distro
Vendor
Version
static void distEndElement(void *state, const xmlChar *name)
{
switch (parserState) {
…
case PARSER_VENDOR:
case PARSER_VERSION:
parserState = PARSER_DISTRO;
…
}
Libxml2 – Libxml2 – SAX parser (3)SAX parser (3)
static xmlSAXHandler distListParser = { …
0, /* startDocument */ 0, /* endDocument */ (startElementSAXFunc) distStartElement, /*startEl*/ (endElementSAXFunc) distEndElement, /*endEl*/ 0, /* reference */
(charactersSAXFunc) distCharacters, /* characters */ …
};
int main(int argc, char **argv){ xmlSAXParseFile(&distListParser, "distros.xml", 0);
return 0;}
Libxml2 – Libxml2 – SAX parser (4)SAX parser (4)
• Libxml2 http://xmlsoft.org
• Benoît Marchal: XML v příkladech, Computer Press
2000
ISBN 80-7226-332-3, http://www.vltava.cz
• Prednáška http://www.meduna.org/xmlpreprog
– Fólie (HTML, PowerPoint)
– Kompilovateľné príklady
ZdrojeZdroje