static const char *xml_parse_left_tag(ACL_XML *xml, const char *data) { int ch; if (LEN(xml->curr_node->ltag) == 0) { SKIP_SPACE(data); } while ((ch = *data) != 0) { data++; if (ch == '>') { xml->curr_node->status = ACL_XML_S_LGT; xml_parse_check_self_closed(xml); if ((xml->curr_node->flag & ACL_XML_F_SELF_CL) && xml->curr_node->last_ch == '/') { acl_vstring_truncate(xml->curr_node->ltag, LEN(xml->curr_node->ltag) - 1); } break; } else if (IS_SPACE(ch)) { xml->curr_node->status = ACL_XML_S_ATTR; xml->curr_node->last_ch = ch; break; } else { ACL_VSTRING_ADDCH(xml->curr_node->ltag, ch); xml->curr_node->last_ch = ch; } } ACL_VSTRING_TERMINATE(xml->curr_node->ltag); return (data); }
static const char *xml_parse_left_tag(ACL_XML2 *xml, const char *data) { int ch; if (xml->curr_node->ltag == xml->addr) SKIP_SPACE(data); if (*data == 0) return data; if (xml->curr_node->ltag == xml->addr) xml->curr_node->ltag = xml->ptr; while ((ch = *data) != 0) { if (ch == '>') { if (xml->len < MIN_LEN) return data; data++; xml->len--; xml->curr_node->ltag_size = xml->ptr - xml->curr_node->ltag; *xml->ptr++ = 0; xml_parse_check_self_closed(xml); if ((xml->curr_node->flag & ACL_XML2_F_SELF_CL) && xml->curr_node->last_ch == '/') { size_t n = xml->curr_node->ltag_size; if (n >= 2) xml->curr_node->ltag[n - 2] = 0; xml->curr_node->status = ACL_XML2_S_RGT; } else xml->curr_node->status = ACL_XML2_S_LGT; break; } else if (IS_SPACE(ch)) { if (xml->len < MIN_LEN) return data; data++; xml->len--; xml->curr_node->ltag_size = xml->ptr - xml->curr_node->ltag; *xml->ptr++ = 0; xml->curr_node->status = ACL_XML2_S_ATTR; xml->curr_node->last_ch = ch; break; } else { if (xml->len < MIN_LEN) return data; data++; xml->len--; *xml->ptr++ = ch; xml->curr_node->last_ch = ch; } } return data; }
static const char *xml_parse_left_tag(ACL_XML2 *xml, const char *data) { int ch; if (xml->curr_node->ltag == xml->dummy) SKIP_SPACE(data); if (*data == 0) return data; if (xml->curr_node->ltag == xml->dummy) xml->curr_node->ltag = END(xml); while ((ch = *data) != 0) { if (ch == '>') { if (NO_SPACE(xml)) return data; xml->curr_node->ltag_size = END(xml) - xml->curr_node->ltag; ADD(xml, '\0'); data++; xml_parse_check_self_closed(xml); if ((xml->curr_node->flag & ACL_XML2_F_SELF_CL) && xml->curr_node->last_ch == '/') { if (xml->curr_node->ltag_size > 0) { size_t n; xml->curr_node->ltag_size--; n = xml->curr_node->ltag_size; xml->curr_node->ltag[n] = 0; } xml->curr_node->status = ACL_XML2_S_RGT; } else xml->curr_node->status = ACL_XML2_S_LGT; break; } else if (IS_SPACE(ch)) { if (NO_SPACE(xml)) return data; data++; xml->curr_node->ltag_size = END(xml) - xml->curr_node->ltag; ADD(xml, '\0'); xml->curr_node->status = ACL_XML2_S_ATTR; xml->curr_node->last_ch = ch; break; } else { if (NO_SPACE(xml)) return data; data++; ADD(xml, ch); xml->curr_node->last_ch = ch; } } return data; }
static const char *xml_parse_attr(ACL_XML *xml, const char *data) { int ch; ACL_XML_ATTR *attr = xml->curr_node->curr_attr; if (attr == NULL || LEN(attr->name) == 0) { SKIP_SPACE(data); /* 略过 ' ', '\t' */ if (*data == 0) return (NULL); SKIP_WHILE(*data == '=', data); if (*data == 0) return (NULL); } if (*data == '>') { xml->curr_node->status = ACL_XML_S_LGT; xml_parse_check_self_closed(xml); xml->curr_node->curr_attr = NULL; data++; return (data); } xml->curr_node->last_ch = *data; if (*data == '/') { data++; return (data); } if (attr == NULL) { attr = acl_xml_attr_alloc(xml->curr_node); xml->curr_node->curr_attr = attr; } while ((ch = *data) != 0) { xml->curr_node->last_ch = ch; if (ch == '=') { xml->curr_node->status = ACL_XML_S_AVAL; data++; break; } if (!IS_SPACE(ch)) ACL_VSTRING_ADDCH(attr->name, ch); data++; } ACL_VSTRING_TERMINATE(attr->name); return (data); }
static const char *xml_parse_attr_val(ACL_XML2 *xml, const char *data) { int ch; ACL_XML2_ATTR *attr = xml->curr_node->curr_attr; if (attr->value == xml->addr && !attr->quote) { SKIP_SPACE(data); if (IS_QUOTE(*data)) attr->quote = *data++; } if (*data == 0) return data; if (attr->value == xml->addr) attr->value = xml->ptr; while ((ch = *data) != 0) { if (attr->quote) { if (ch == attr->quote) { if (xml->len < MIN_LEN) return data; data++; xml->len--; attr->value_size = xml->ptr - attr->value; *xml->ptr++ = 0; xml->curr_node->status = ACL_XML2_S_ATTR; xml->curr_node->last_ch = ch; break; } if (xml->len < MIN_LEN) return data; xml->len--; *xml->ptr++ = ch; xml->curr_node->last_ch = ch; } else if (ch == '>') { if (xml->len < MIN_LEN) return data; data++; xml->len--; attr->value_size = xml->ptr - attr->value; *xml->ptr++ = 0; xml_parse_check_self_closed(xml); if ((xml->curr_node->flag & ACL_XML2_F_SELF_CL) && xml->curr_node->last_ch == '/') { if (attr->value_size >= 2) attr->value[attr->value_size - 2] = 0; xml->curr_node->status = ACL_XML2_S_RGT; } else xml->curr_node->status = ACL_XML2_S_LGT; break; } else if (IS_SPACE(ch)) { if (xml->len < MIN_LEN) return data; data++; xml->len--; attr->value_size = xml->ptr - attr->value; *xml->ptr++ = 0; xml->curr_node->status = ACL_XML2_S_ATTR; xml->curr_node->last_ch = ch; break; } else { if (xml->len < MIN_LEN) return data; xml->len--; *xml->ptr++ = ch; xml->curr_node->last_ch = ch; } data++; } /* 说明属性值还未解析完,需要继续解析 */ if (xml->curr_node->status == ACL_XML2_S_AVAL) return data; /* 当状态发生改变时,则说明属性值已经完毕 */ if ((xml->flag & ACL_XML2_FLAG_XML_DECODE) && attr->value_size > 1 && xml->len > 0) { const char *val = attr->value; attr->value = xml->ptr; (void) acl_xml_decode2(val, &xml->ptr, &xml->len); attr->value_size = xml->ptr - attr->value - 1; } /* 将该标签ID号映射至哈希表中,以便于快速查询 */ if (IS_ID(attr->name) && *attr->value != 0) { const char *ptr = attr->value; /* 防止重复ID被插入现象 */ if (acl_htable_find(xml->id_table, ptr) == NULL) { acl_htable_enter(xml->id_table, ptr, attr); /* 当该属性被加入哈希表后才会赋于节点 id */ xml->curr_node->id = attr->value; } } /* 必须将该节点的当前属性对象置空,以便于继续解析时 * 可以创建新的属性对象 */ xml->curr_node->curr_attr = NULL; return data; }
static const char *xml_parse_attr(ACL_XML2 *xml, const char *data) { int ch; ACL_XML2_ATTR *attr = xml->curr_node->curr_attr; if (attr == NULL || attr->name == xml->addr) { SKIP_SPACE(data); SKIP_WHILE(*data == '=', data); } if (*data == 0) return data; if (*data == '>') { xml_parse_check_self_closed(xml); if ((xml->curr_node->flag & ACL_XML2_F_SELF_CL) && xml->curr_node->last_ch == '/') { xml->curr_node->status = ACL_XML2_S_RGT; } else xml->curr_node->status = ACL_XML2_S_LGT; xml->curr_node->curr_attr = NULL; if (xml->len < MIN_LEN) return data; data++; xml->len--; *xml->ptr++ = 0; return data; } xml->curr_node->last_ch = *data; if (*data == '/') { data++; /* 此处返回后会触发本函数再次被调用,当下一个字节为 '>' 时, * 上面通过调用 xml_parse_check_self_closed 检查是否为自封闭 * 标签: "/>" */ return data; } if (attr == NULL) { attr = acl_xml2_attr_alloc(xml->curr_node); xml->curr_node->curr_attr = attr; attr->name = xml->ptr; } while ((ch = *data) != 0) { xml->curr_node->last_ch = ch; if (ch == '=') { if (xml->len < MIN_LEN) return data; data++; xml->len--; attr->name_size = xml->ptr - attr->name; *xml->ptr++ = 0; xml->curr_node->status = ACL_XML2_S_AVAL; break; } if (!IS_SPACE(ch)) { if (xml->len < MIN_LEN) return data; xml->len--; *xml->ptr++ = ch; } data++; } return data; }
static char *xml_parse_attr_val(ACL_XML3 *xml, char *data) { int ch; ACL_XML3_ATTR *attr = xml->curr_node->curr_attr; if (attr->value == xml->addr && !attr->quote) { SKIP_SPACE(data); if (IS_QUOTE(*data)) attr->quote = *data++; } if (*data == 0) return data; if (attr->value == xml->addr) attr->value = data; while ((ch = *data) != 0) { if (attr->quote) { if (ch == attr->quote) { attr->value_size = data - attr->value; xml->curr_node->status = ACL_XML3_S_ATTR; xml->curr_node->last_ch = ch; *data++ = 0; break; } xml->curr_node->last_ch = ch; } else if (ch == '>') { if (attr->value_size == 0) attr->value_size = data - attr->value; *data++ = 0; xml_parse_check_self_closed(xml); if ((xml->curr_node->flag & ACL_XML3_F_SELF_CL) && xml->curr_node->last_ch == '/') { if (attr->value_size >= 2) attr->value[attr->value_size - 2] = 0; xml->curr_node->status = ACL_XML3_S_RGT; } else xml->curr_node->status = ACL_XML3_S_LGT; break; } else if (IS_SPACE(ch)) { attr->value_size = data - attr->value; xml->curr_node->status = ACL_XML3_S_ATTR; xml->curr_node->last_ch = ch; *data++ = 0; break; } else xml->curr_node->last_ch = ch; data++; } /* 当状态发生改变时,则说明属性值已经完毕 */ if (xml->curr_node->status != ACL_XML3_S_AVAL) { /* 将该标签ID号映射至哈希表中,以便于快速查询 */ if (IS_ID(attr->name) && *attr->value != 0) { char *ptr = attr->value; /* 防止重复ID被插入现象 */ if (acl_htable_find(xml->id_table, ptr) == NULL) { acl_htable_enter(xml->id_table, ptr, attr); /* 当该属性被加入哈希表后才会赋于节点 id */ xml->curr_node->id = attr->value; } } /* 必须将该节点的当前属性对象置空,以便于继续解析时 * 可以创建新的属性对象 */ xml->curr_node->curr_attr = NULL; } return data; }
static const char *xml_parse_attr_val(ACL_XML *xml, const char *data) { int ch; ACL_XML_ATTR *attr = xml->curr_node->curr_attr; if (LEN(attr->value) == 0 && !attr->quote) { SKIP_SPACE(data); if (IS_QUOTE(*data)) { attr->quote = *data++; } if (*data == 0) { return (NULL); } } while ((ch = *data) != 0) { if (attr->backslash) { ACL_VSTRING_ADDCH(attr->value, ch); xml->curr_node->last_ch = ch; attr->backslash = 0; } else if (ch == '\\') { if (attr->part_word) { ACL_VSTRING_ADDCH(attr->value, ch); attr->part_word = 0; } else attr->backslash = 1; } else if (attr->quote) { if (ch == attr->quote) { xml->curr_node->status = ACL_XML_S_ATTR; xml->curr_node->last_ch = ch; data++; break; } ACL_VSTRING_ADDCH(attr->value, ch); xml->curr_node->last_ch = ch; } else if (ch == '>') { xml->curr_node->status = ACL_XML_S_LGT; xml_parse_check_self_closed(xml); data++; break; } else if (IS_SPACE(ch)) { xml->curr_node->status = ACL_XML_S_ATTR; xml->curr_node->last_ch = ch; data++; break; } else { ACL_VSTRING_ADDCH(attr->value, ch); xml->curr_node->last_ch = ch; if ((xml->flag & ACL_XML_FLAG_PART_WORD)) { /* 处理半个汉字的情形 */ if (attr->part_word) attr->part_word = 0; else if (ch < 0) attr->part_word = 1; } } data++; } ACL_VSTRING_TERMINATE(attr->value); if (xml->curr_node->status != ACL_XML_S_AVAL) { /* 将该标签ID号映射至哈希表中,以便于快速查询 */ if (IS_ID(STR(attr->name)) && LEN(attr->value) > 0) { const char *ptr = STR(attr->value); /* 防止重复ID被插入现象 */ if (acl_htable_find(xml->id_table, ptr) == NULL) { acl_htable_enter(xml->id_table, ptr, attr); /* 只有当该属性被加入哈希表后才会赋于结点的 id */ xml->curr_node->id = attr->value; } } /* 必须将该结点的当前属性对象置空,以便于继续解析时 * 可以创建新的属性对象 */ xml->curr_node->curr_attr = NULL; } return (data); }