====== 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 =====