C - libmxml 用法

使用 libmxml 解析 xml 文字的用法


定義


mxml_node_t *mxmlLoadString(mxml_node_t *top, const char *s, mxml_type_t (*cb)(mxml_node_t *));
mxml_node_t *mxmlLoadFile(mxml_node_t *top, FILE *fp, mxml_type_t (*cb)(mxml_node_t *));
int mxmlSaveFile(mxml_node_t *node, FILE *fp, mxml_save_cb_t cb);
char *mxmlSaveAllocString(mxml_node_t *node, mxml_save_cb_t (*cb)(mxml_save_cb_t *));

mxml_node_t *mxmlNewXML(const char *version);
mxml_node_t *mxmlNewElement(mxml_node_t *parent, const char *name);
mxml_node_t *mxmlFindElement(mxml_node_t *node, mxml_node_t *top, const char *name, const char *attr, const char *value, int descend);
const char *mxmlElementGetAttr(mxml_node_t *node, const char *name);
void mxmlElementSetAttr(mxml_node_t *node, const char *name, const char *value);
void mxmlElementDeleteAttr(mxml_node_t *node, const char *name);
void mxmlAdd(mxml_node_t *parent, int where, mxml_node_t *child, mxml_node_t *node);
void mxmlDelete(mxml_node_t *node);
void mxmlRemove(mxml_node_t *node);
void mxmlSetWrapMargin(int column);



尋找節點


MXML_NODE *topNode;
MXML_NODE *nextNode;
MXML_NODE *node = mxmlFindElement(nextNode, topNode, "tagName", NULL, NULL, MXML_DESCEND);



取得節點參數值


char *get_xml_attr(MXML_NODE *node, char *name, char *attrName)
{
return mxmlElementGetAttr(mxmlFindElement(node, node, name, NULL, NULL, MXML_DESCEND), attrName);
}


取得節點內容


char *get_xml_value(MXML_NODE *pnode, char *name)
{
char *value = NULL;
MXML_NODE *node = NULL;
if ((node = mxmlFindElement(pnode, pnode, name, NULL, NULL, MXML_DESCEND))) {
if (node->child && (node->child->type == MXML_TEXT)) {
value = strdup(node->child->value.text.string);
}
}
return value;
}





歷遍所有 XML 節點


enum {
MXML_CONTENT_TYPE_HEAD,
MXML_CONTENT_TYPE_DATA,
MXML_CONTENT_TYPE_TAIL,
};
char *my_mxmlParse(MXML_NODE *nodeTop, void *_data, void (*parse_func)(void *_data, int type, char *name, char *value)) {
MXML_NODE *node;
char *name, *value = NULL;
node = nodeTop;
while(node) {
name = node->value.element.name;
if(name == 0x1) { // 當內容是 "--- cc ---",可能是含有 '-' 這個符號。就會造成這裡的 name = 0x1(原本應該是NULL),所以去使用到name就會core dump
name = NULL;
}
if(node->child) {
if(node->child->child) {
parse_func(_data, MXML_CONTENT_TYPE_HEAD, name, NULL); // ("<%s>", name)
}
value = my_mxmlParse(node->child, _data, parse_func);
if(value) {
parse_func(_data, MXML_CONTENT_TYPE_DATA, name, value); // ("<%s>%s</%s>", name, value, name)
} else {
if(strncmp(name, "?xml", 4))
parse_func(_data, MXML_CONTENT_TYPE_TAIL, name, NULL); // ("</%s>", name)
}
} else {
if(!node->next && !name)
return node->value.text.string;
parse_func(_data, MXML_CONTENT_TYPE_DATA, name, ((node->value.element.attrs) ? node->value.element.attrs->value : NULL)); // ("<%s value=\"\"></%s>", name, name)
}
node = node->next;
}
return NULL;
}
void parse_func(void *_data, int type, char *name, char *value) {
switch(type) {
case MXML_CONTENT_TYPE_HEAD:
printf("<%s>", name);
break;
case MXML_CONTENT_TYPE_DATA:
printf("<%s>%s</%s>", name, (value ? value : ""), name);
break;
case MXML_CONTENT_TYPE_TAIL:
printf("</%s>", name);
break;
}
}
int main(int argc, char **argv) {
char *xml = "<topTag><a>aa</a><b>bb</b></topTag>";
MXML_NODE *topNode = NULL;
if((topNode = mxmlLoadString(NULL, xml, MXML_NO_CALLBACK))) {
my_mxmlParse(topNode, NULL, parse_func);
}
}





沒有留言:

張貼留言