====== XML ====== * XML * každé XML má kořen - tj. hlavní element * element je ohraničen startovací a ukončovací značkou * například: ''..'' - neprázdný element s názvem element1 * například: '''' - prázdný element s názvem element1 * element může mít atributy * například: ''..'' * element může mít i návěští * například: '''' * jako uzel se označuje element nebo hodnota elementu * existuje více způsobů jak s XML pracovat, nejčastěji: * pomocí parseru * DOM (DOM = Document Object Model) - z XML vyrobí obraz (strom) v paměti. * SAX (SAX = Simple API for XML) - postupně prochází XML a vyvolává události (uživatelské callback). * pomocí [[http://www.w3schools.com/xsl/xpath_intro.asp|xpath]] - vyhledání elementů výrazem * přímé procházení voláním funkcí (tj. dej další uzel, dej potomky, .. ) {{:xml-decision-diag.png?500|http://stackoverflow.com/questions/9387610/what-xml-parser-should-i-use-in-c}} ===== libXML2 ===== * [[http://xmlsoft.org/tutorial/index.html|tutoriál vhodný pro začátek]] * [[http://www.xmlsoft.org/html/index.html|programátorská dokumentace]] * podporuje SAX i Xpath * měl jsem ale případ XML, kde mi ani jedno řešení nepřišlo vhodné * použil jsem přímé procházení, viz následující příklad ===== Přímé procházení ===== 2016-04-01 10:00 .. .. void parseCfg(xmlDocPtr doc, xmlNodePtr cur) { xmlChar *key; cur = cur->xmlChildrenNode; while (cur != NULL) { if (cur->type == XML_ELEMENT_NODE) { if ((!xmlStrcmp(cur->name, (const xmlChar *)"timestamp"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); xmlFree(key); } if ((!xmlStrcmp(cur->name, (const xmlChar *)"methods"))) { parseMet(doc, cur->xmlChildrenNode); } if ((!xmlStrcmp(cur->name, (const xmlChar *)"syssettings"))) { parsePref(doc, cur->xmlChildrenNode); } } cur = cur->next; } return; } int parseXmlBuf(const char *buf, int size) { xmlDocPtr doc; xmlNodePtr cur; doc = xmlParseMemory(buf,size); if (doc == NULL ) { return 1; } cur = xmlDocGetRootElement(doc); if (cur == NULL) { xmlFreeDoc(doc); return 2; } // check if the buf is XML configuration (root equal to configuration} if (xmlStrcmp(cur->name, (const xmlChar *) "configuration")) { xmlFreeDoc(doc); return 3; } parseCfg(doc, cur); xmlFreeDoc(doc); return 0; } * ukázka parsování atributů .. .. // look for parameters while (cur != NULL) { if (cur->type == XML_ELEMENT_NODE) { if ((!xmlStrcmp(cur->name, (const xmlChar *)"parameter"))) { // look for name and value of parameter char *name = NULL; char *value = NULL; xmlAttr *attribute = NULL; attribute = cur->properties; while(attribute && attribute->name && attribute->children) { if ((!xmlStrcmp(attribute->name, (const xmlChar *)"name"))) { if (name) xmlFree(name); name = (char*)xmlNodeListGetString(cur->doc, attribute->children, 1); } if ((!xmlStrcmp(attribute->name, (const xmlChar *)"value"))) { if (value) xmlFree(value); value = (char*)xmlNodeListGetString(cur->doc, attribute->children, 1); } attribute = attribute->next; } if ((value)&&(name)) { if (!strcmp((char*)name,"extServices")) { ext_allowed = (!strcmp((char*)value,"1")); } } if (name) xmlFree(name); if (value) xmlFree(value); } } cur = cur->next; } ===== Vyhledávání přes Xpath =====