XML pre programátorov 7. víkend s Linuxom 5. – 6. október 2002 Žilina Stanislav Meduna ETM Aktiengesellschaft
Obsah Č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 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
Extensible XML definuje iba štruktúru Žiadne preddefinované značky Konkrétne značky sú vecou aplikácie Dokonalá rozšíriteľnosť
Markup Stromová štruktúra Značky –Elementy –Atribúty Obsah (vlastné informácie) Entity
Language 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ž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? 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 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í – model FreeOnly DistList Distro Packaging VendorVersionCodeNamePackage File Name Version Release Free 0..n n
Zoznam distribúcií – DTD (1) <!ATTLIST Distro FreeOnly (%bool;) "false" Packaging (rpm|deb|tgz|other|none) "rpm" >
Zoznam distribúcií – DTD (2) <!ATTLIST Package Name CDATA #REQUIRED Version CDATA #REQUIRED Release CDATA "" Free (%bool;) "true" >
Zoznam distribúcií – dokument (1) Red Hat 7.3 Valhalla /usr/share/pixmaps/redhat/shadowman-32.png Debian Potato
Zoznam distribúcií – dokument (2)... Red Hat 7.3 Valhalla /usr/share/pixmaps/redhat/shadowman-32.png...
Parsery 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
libxml2 Linux / Unix / Windows MIT licencia Obyčajné C Objektové aj udalostné rozhranie Mnoho pohodlných vlastností
DOM FreeOnly Document DistList Packaging VendorCodeName Root element Distro children parent next prev children properties next content Valhalla rpm
SAX – stavový automat DistList Distro Vendor Version CodeName startElement endElement Package Vendor
SAX – callbacky <Distro FreeOnly="false" Packaging="rpm" > Red Hat startElement("Distro", { "FreeOnly", "false", "Packaging", "rpm", NULL }) startElement("DistList", { NULL }) startElement("Vendor", { NULL }) characters("Red Hat") endElement("Vendor“)
Libxml2 – DOM parser (1) #include 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 parser (2) 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 next children properties
Libxml2 – DOM parser (3) 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; } VendorCodeName next FreeOnlyPackaging next
Libxml2 – 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 – 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 – 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 – SAX parser (4)
Libxml2 Benoît Marchal: XML v příkladech, Computer Press 2000 ISBN , Prednáška –Fólie (HTML, PowerPoint) –Kompilovateľné príklady Zdroje
Stanislav Meduna ETM Aktiengesellschaft