280 likes | 436 Views
XML pre programátorov. 7. víkend s Linuxom 5. – 6. október 2002 Žilina Stanislav Meduna ETM Aktiengesellschaft stano@meduna.org. 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.
E N D
XML pre programátorov 7. víkend s Linuxom 5. – 6. október 2002 Žilina Stanislav Meduna ETM Aktiengesellschaft stano@meduna.org
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 DistList 0..n FreeOnly Distro Packaging 0..1 0..1 0..n Name Vendor Version CodeName Package Version Release 0..n File Free
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) <!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) <?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) ... <Distro FreeOnly="false" Packaging="rpm"> <Vendor>Red Hat</Vendor> <Version>7.3</Version> <CodeName>Valhalla</CodeName> <PackageName="basesystem" Version="7.0"Release="2"/> <PackageName="redhat-logos" Version="2.5.12" Release="1" Free="false"> <File>/usr/share/pixmaps/redhat/shadowman-32.png</File> </Package> </Distro> ...
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 Document Root element children DistList parent next Distro Distro prev children next Vendor CodeName Valhalla content properties next FreeOnly Packaging rpm content
SAX – stavový automat DistList endElement startElement Package Distro Vendor Vendor Version CodeName
SAX – callbacky <DistList> <Distro FreeOnly="false" Packaging="rpm" > <Vendor> Red Hat </Vendor> startElement("DistList", { NULL }) startElement("Distro", { "FreeOnly", "false", "Packaging", "rpm", NULL }) startElement("Vendor", { NULL }) characters("Red Hat") endElement("Vendor“)
Libxml2 – DOM parser (1) #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 Root El DistList children Distro
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"); } Distro next Distro children Vendor properties FreeOnly
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; } } next Vendor CodeName next FreeOnly Packaging
Libxml2 – SAX parser (1) static enum { PARSER_START, PARSER_DISTLIST, PARSER_DISTRO, … } parserState = PARSER_START; …
Libxml2 – SAX parser (2) 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; … Distro Vendor Version
Libxml2 – SAX parser (3) static void distEndElement(void *state, const xmlChar *name) { switch (parserState) { … case PARSER_VENDOR: case PARSER_VERSION: parserState = PARSER_DISTRO; … } Distro Vendor Version
Libxml2 – SAX parser (4) 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; }
Zdroje • Libxml2http://xmlsoft.org • Benoît Marchal: XML v příkladech, Computer Press 2000ISBN 80-7226-332-3, http://www.vltava.cz • Prednáška http://www.meduna.org/xmlpreprog • Fólie (HTML, PowerPoint) • Kompilovateľné príklady
Stanislav Meduna ETM Aktiengesellschaft stano@meduna.org