#include "lib_acl.h"
#define STR acl_vstring_str
static const char *__data1 =
"\r\n"
"\r\n"
"\txmllint\">\r\n"
"]>\r\n"
"\r\n"
" user zsx11 \r\n"
" user zsx12 \r\n"
" my age\r\n"
" "
" "
" mobile number "
" mobile number "
" "
" "
" \r\n"
" user zsx13 \r\n"
"\r\n"
"\r\n"
" user zsx21 \r\n"
" user zsx22 \r\n"
" \r\n"
" my age\r\n"
" \r\n"
" user zsx23 \r\n"
"\r\n"
"\r\n"
" user zsx31 \r\n"
" user zsx32 \r\n"
" user zsx33 \r\n"
" bao bao \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" user zsx34 \r\n"
"\r\n";
static const char *__data2 =
"\r\n"
"\r\n"
"xmllint\">\r\n"
"]>\r\n"
"test\r\n"
" - -->\r\n"
" zsx\r\n"
" 38\r\n"
" \r\n"
"\r\n"
" -->\r\n"
"\r\n"
"\r\n"
"test\r\n";
static const char *__data3 = "hello hi
\r\n";
static const char* __data4 = "\r\n"
"\r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
"\r\n";
static const char* __data5 = "\r\n"
"\r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
"\r\n";
static const char* __data6 = "\r\n"
"\r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
"\r\n";
static const char* __data7 = "\r\n"
"\r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
" \r\n"
"\r\n";
static void parse_xml_benchmark(int once, int use_cache, int max, const char *data)
{
int i;
ACL_XML *xml = acl_xml_alloc();
acl_xml_slash(xml, 1);
if (use_cache)
acl_xml_cache(xml, 100);
ACL_METER_TIME("-------------bat begin--------------");
for (i = 0; i < max; i++) {
const char *ptr = data;
if (once) {
acl_xml_parse(xml, ptr);
} else {
/* 每次仅输入一个字节来分析 xml 数据 */
while (*ptr != 0) {
char ch2[2];
ch2[0] = *ptr;
ch2[1] = 0;
acl_xml_parse(xml, ch2);
ptr++;
}
}
if (i < 2 || i == 4) {
printf("--------- dump xml --------------\n");
acl_xml_dump(xml, ACL_VSTREAM_OUT);
printf("--------- data src --------------\n");
printf("%s", data);
printf("--------- dump end --------------\n");
}
acl_xml_reset(xml);
}
ACL_METER_TIME("-------------bat end--------------");
acl_xml_free(xml);
}
static void build_xml(ACL_XML *xml, const char *data)
{
ACL_VSTRING *buf = acl_xml_build(xml, NULL);
ACL_FILE *fp = acl_fopen("./build_xml.txt", "wb");
acl_assert(fp);
printf("--------------in build_xml -------------------\n");
printf("%s\r\n", acl_vstring_str(buf));
acl_fwrite(acl_vstring_str(buf), ACL_VSTRING_LEN(buf), 1, fp);
printf("----------------------------------------------\n");
printf("%s\r\n", data);
acl_fclose(fp);
printf("--------------end in build_xml----------------\n");
acl_vstring_free(buf);
}
static void parse_xml(int once, const char *data)
{
ACL_XML *xml = acl_xml_alloc();
const char *ptr;
ACL_ITER iter1;
int i, total, left;
ACL_ARRAY *a;
ACL_XML_NODE *pnode;
ptr = data;
if (once) {
/* 一次性地分析完整 xml 数据 */
ACL_METER_TIME("-------------once begin--------------");
acl_xml_parse(xml, ptr);
} else {
/* 每次仅输入一个字节来分析 xml 数据 */
ACL_METER_TIME("-------------stream begin--------------");
while (*ptr != 0) {
char ch2[2];
ch2[0] = *ptr;
ch2[1] = 0;
acl_xml_parse(xml, ch2);
ptr++;
}
}
ACL_METER_TIME("-------------end--------------");
printf("enter any key to continue ...\n");
getchar();
if (acl_xml_is_complete(xml, "root")) {
printf(">> Yes, the xml complete\n");
} else {
printf(">> No, the xml not complete\n");
}
total = xml->node_cnt;
/* 遍历根结点的一级子结点 */
acl_foreach(iter1, xml->root) {
ACL_ITER iter2;
ACL_XML_NODE *node = (ACL_XML_NODE*) iter1.data;
printf("tag> %s, text: %s\n", STR(node->ltag), STR(node->text));
/* 遍历一级子结点的二级子结点 */
acl_foreach(iter2, node) {
ACL_ITER iter3;
ACL_XML_NODE *node2 = (ACL_XML_NODE*) iter2.data;
printf("\ttag> %s, text: %s\n", STR(node2->ltag), STR(node2->text));
/* 遍历二级子结点的属性 */
acl_foreach(iter3, node2->attr_list) {
ACL_XML_ATTR *attr = (ACL_XML_ATTR*) iter3.data;
printf("\t\tattr> %s: %s\n", STR(attr->name), STR(attr->value));
}
}
}
printf("----------------------------------------------------\n");
/* 从根结点开始遍历 xml 对象的所有结点 */
acl_foreach(iter1, xml) {
ACL_ITER iter2;
ACL_XML_NODE *node = (ACL_XML_NODE*) iter1.data;
for (i = 1; i < node->depth; i++) {
printf("\t");
}
printf("tag> %s, text: %s\n", STR(node->ltag), STR(node->text));
/* 遍历 xml 结点的属性 */
acl_foreach(iter2, node->attr_list) {
ACL_XML_ATTR *attr = (ACL_XML_ATTR*) iter2.data;
for (i = 1; i < node->depth; i++) {
printf("\t");
}
printf("\tattr> %s: %s\n", STR(attr->name), STR(attr->value));
}
}
/* 根据标签名获得 xml 结点集合 */
printf("--------- acl_xml_getElementsByTagName ----------\n");
a = acl_xml_getElementsByTagName(xml, "user");
if (a) {
/* 遍历结果集 */
acl_foreach(iter1, a) {
ACL_XML_NODE *node = (ACL_XML_NODE*) iter1.data;
printf("tag> %s, text: %s\n", STR(node->ltag), STR(node->text));
}
/* 释放数组对象 */
acl_xml_free_array(a);
}
/* 查询属性名为 name, 属性值为 user2_1 的所有 xml 结点的集合 */
printf("--------- acl_xml_getElementsByName ------------\n");
a = acl_xml_getElementsByName(xml, "user2_1");
if (a) {
/* 遍历结果集 */
acl_foreach(iter1, a) {
ACL_XML_NODE *node = (ACL_XML_NODE*) iter1.data;
printf("tag> %s, text: %s\n", STR(node->ltag), STR(node->text));
}
/* 释放数组对象 */
acl_xml_free_array(a);
}
/* 查询属性名为 id, 属性值为 id2_2 的所有 xml 结点集合 */
printf("----------- acl_xml_getElementById -------------\n");
pnode = acl_xml_getElementById(xml, "id2_2");
if (pnode) {
printf("tag> %s, text: %s\n", STR(pnode->ltag), STR(pnode->text));
/* 遍历该 xml 结点的属性 */
acl_foreach(iter1, pnode->attr_list) {
ACL_XML_ATTR *attr = (ACL_XML_ATTR*) iter1.data;
printf("\tattr_name: %s, attr_value: %s\n",
STR(attr->name), STR(attr->value));
}
pnode = acl_xml_node_next(pnode);
printf("----------------- the id2_2's next node is ---------------------\n");
if (pnode) {
printf("-------------- walk node -------------------\n");
/* 遍历该 xml 结点的属性 */
acl_foreach(iter1, pnode->attr_list) {
ACL_XML_ATTR *attr = (ACL_XML_ATTR*) iter1.data;
printf("\tattr_name: %s, attr_value: %s\n",
STR(attr->name), STR(attr->value));
}
} else {
printf("-------------- null node -------------------\n");
}
}
pnode = acl_xml_getElementById(xml, "id2_3");
if (pnode) {
int ndel = 0, node_cnt;
/* 删除该结点及其子结点 */
printf(">>>before delete %s, total: %d\n", STR(pnode->ltag), xml->node_cnt);
ndel = acl_xml_node_delete(pnode);
node_cnt = xml->node_cnt;
printf(">>>after delete id2_3(%d deleted), total: %d\n", ndel, node_cnt);
}
acl_foreach(iter1, xml) {
ACL_XML_NODE *node = (ACL_XML_NODE*) iter1.data;
printf(">>tag: %s\n", STR(node->ltag));
}
pnode = acl_xml_getElementById(xml, "id2_3");
if (pnode) {
printf("-------------- walk %s node -------------------\n", STR(pnode->ltag));
/* 遍历该 xml 结点的属性 */
acl_foreach(iter1, pnode->attr_list) {
ACL_XML_ATTR *attr = (ACL_XML_ATTR*) iter1.data;
printf("\tattr_name: %s, attr_value: %s\n",
STR(attr->name), STR(attr->value));
}
} else {
printf("---- the id2_3 be deleted----\n");
}
build_xml(xml, data);
/* 释放 xml 对象 */
left = acl_xml_free(xml);
printf("free all node ok, total(%d), left is: %d\n", total, left);
}
static void parse_xml_file(const char *filepath, int once)
{
char *data = acl_vstream_loadfile(filepath);
ACL_VSTREAM *fp;
char *ptr;
ACL_XML *xml;
struct timeval begin, end;
if (data == NULL)
return;
gettimeofday(&begin, NULL);
/* 创建 xml 对象 */
xml = acl_xml_alloc();
ptr = data;
if (once) {
/* 一次性地分析完整 xml 数据 */
acl_xml_parse(xml, ptr);
} else {
/* 每次仅输入一个字节来分析 xml 数据 */
while (*ptr) {
char ch2[2];
ch2[0] = *ptr;
ch2[1] = 0;
acl_xml_parse(xml, ch2);
ptr++;
}
}
gettimeofday(&end, NULL);
printf("------ok, time: %ld seconds, %ld microseconds -------\r\n",
(long) end.tv_sec - (long) begin.tv_sec,
(long) end.tv_usec - (long) begin.tv_usec);
fp = acl_vstream_fopen("dump.txt", O_RDWR | O_CREAT | O_TRUNC, 0600, 4096);
/* 将 xml 对象转储至指定流中 */
acl_xml_dump(xml, fp);
acl_vstream_fclose(fp);
acl_xml_free(xml);
acl_myfree(data);
}
static void build_xml2(void)
{
ACL_XML *xml = acl_xml_alloc();
ACL_XML_NODE *node1, *node2, *node3;
ACL_VSTRING *buf;
node1 = acl_xml_create_node(xml, "users", "text1");
acl_xml_node_add_child(xml->root, node1);
(void) acl_xml_node_add_attr(node1, "name", "users list");
node2 = acl_xml_create_node(xml, "user", "text11");
acl_xml_node_add_child(node1, node2);
acl_xml_node_add_attrs(node2, "name", "user11", "value", "zsx11", NULL);
node3 = acl_xml_create_node(xml, "age", "text111");
acl_xml_node_add_child(node2, node3);
acl_xml_node_add_attrs(node3, "name", "user111", "value", "zsx111", NULL);
node2 = acl_xml_create_node(xml, "user", "text2");
acl_xml_node_add_child(node1, node2);
acl_xml_node_add_attrs(node2, "name", "value2", "value", "zsx2", NULL);
node2 = acl_xml_create_node(xml, "user", "text3");
acl_xml_node_add_child(node1, node2);
acl_xml_node_add_attrs(node2, "name", "value3", "value", "zsx3", NULL);
buf = acl_xml_build(xml, NULL);
printf("--------------------xml string-------------------\r\n");
printf("%s\n", acl_vstring_str(buf));
acl_vstring_free(buf);
acl_xml_free(xml);
}
static void test1(void)
{
const char* data = "\r\n"
"\r\n"
"\txmllint\">\r\n"
"]>\r\n"
"\r\n";
ACL_XML *xml = acl_xml_alloc();
ACL_ITER node_it, attr_it;
ACL_XML_NODE *node;
const char *encoding, *type, *href;
printf("data: %s\r\n", data);
acl_xml_update(xml, data);
acl_foreach(node_it, xml) {
ACL_XML_NODE *tmp = (ACL_XML_NODE*) node_it.data;
printf("tag: %s\r\n", STR(tmp->ltag));
acl_foreach(attr_it, tmp->attr_list) {
ACL_XML_ATTR *attr = (ACL_XML_ATTR*) attr_it.data;
printf("\tattr_name: %s, attr_value: %s\r\n",
STR(attr->name), STR(attr->value));
}
}
printf("------------------------------------------------------\r\n");
encoding = acl_xml_getEncoding(xml);
type = acl_xml_getType(xml);
node = acl_xml_getElementMeta(xml, "xml-stylesheet");
if (node)
href = acl_xml_getElementAttrVal(node, "href");
else
href = NULL;
printf("xml encoding: %s, type: %s, href: %s\r\n",
encoding ? encoding : "null", type ? type : "null",
href ? href : "null");
acl_xml_free(xml);
}
static void usage(const char *procname)
{
printf("usage: %s -h[help]"
" -f {xml_file}\n"
" -s[parse once]\n"
" -M[use mempool]\n"
" -b[benchmark] -c[cache xml node] -m benchmark_max\n"
" -p[print] data1|data2|data3|data4|data5|data6|data7\n"
" -d[which data] data1|data2|data3|data4|data5|data6|data7\n",
procname);
}
#ifdef WIN32
#define snprintf _snprintf
#endif
int main(int argc, char *argv[])
{
int ch, once = 0, bench_max = 10000;
char filepath[256];
int benchmark = 0, use_mempool = 0, use_cache = 0;
const char *data = __data1;
if (0) {
test1(); getchar(); exit(0);
}
snprintf(filepath, sizeof(filepath), "xmlcatalog_man.xml");
while ((ch = getopt(argc, argv, "hf:sbm:cMp:d:")) > 0) {
switch (ch) {
case 'h':
usage(argv[0]);
return (0);
case 'f':
snprintf(filepath, sizeof(filepath), "%s", optarg);
break;
case 's':
once = 1;
break;
case 'b':
benchmark = 1;
break;
case 'M':
use_mempool = 1;
break;
case 'c':
use_cache = 1;
break;
case 'm':
bench_max = atoi(optarg);
break;
case 'd':
if (strcasecmp(optarg, "data2") == 0)
data = __data2;
else if (strcasecmp(optarg, "data3") == 0)
data = __data3;
else if (strcasecmp(optarg, "data4") == 0)
data = __data4;
else if (strcasecmp(optarg, "data5") == 0)
data = __data5;
else if (strcasecmp(optarg, "data6") == 0)
data = __data6;
else if (strcasecmp(optarg, "data7") == 0)
data = __data7;
break;
case 'p':
if (strcasecmp(optarg, "data1") == 0)
printf("%s\n", __data1);
else if (strcasecmp(optarg, "data2") == 0)
printf("%s\n", __data2);
else if (strcasecmp(optarg, "data3") == 0)
printf("%s\n", __data3);
else if (strcasecmp(optarg, "data4") == 0)
printf("%s\n", __data4);
else if (strcasecmp(optarg, "data5") == 0)
printf("%s\n", __data5);
else if (strcasecmp(optarg, "data6") == 0)
printf("%s\n", __data6);
else if (strcasecmp(optarg, "data7") == 0)
printf("%s\n", __data7);
return (0);
default:
break;
}
}
if (use_mempool)
acl_mem_slice_init(8, 1024, 100000,
ACL_SLICE_FLAG_GC2 |
ACL_SLICE_FLAG_RTGC_OFF |
ACL_SLICE_FLAG_LP64_ALIGN);
if (benchmark) {
parse_xml_benchmark(once, use_cache, bench_max, data);
return (0);
}
parse_xml(once, data);
parse_xml_file(filepath, once);
build_xml2();
#ifdef ACL_MS_WINDOWS
printf("ok, enter any key to exit ...\n");
getchar();
#endif
return 0;
}