⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 srw.c

📁 harvest是一个下载html网页得机器人
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 2002-2003, Index Data. * See the file LICENSE for details. * * $Id: srw.c,v 1.15 2003/05/12 22:36:10 adam Exp $ */#include <yaz/srw.h>#if HAVE_XML2#include <libxml/parser.h>#include <libxml/tree.h>static void add_XML_n(xmlNodePtr ptr, const char *elem, char *val, int len){    if (val)    {        xmlDocPtr doc = xmlParseMemory(val,len);        if (doc)        {            xmlNodePtr c = xmlNewChild(ptr, 0, elem, 0);            xmlNodePtr t = xmlDocGetRootElement(doc);            xmlAddChild(c, xmlCopyNode(t,1));            xmlFreeDoc(doc);        }    }}static void add_xsd_string_n(xmlNodePtr ptr, const char *elem, char *val,                             int len){    if (val)    {        xmlNodePtr c = xmlNewChild(ptr, 0, elem, 0);        xmlNodePtr t = xmlNewTextLen(val, len);        xmlAddChild(c, t);    }}static void add_xsd_string(xmlNodePtr ptr, const char *elem, char *val){    if (val)        xmlNewChild(ptr, 0, elem, val);}static void add_xsd_integer(xmlNodePtr ptr, const char *elem, int *val){    if (val)    {        char str[30];        sprintf(str, "%d", *val);        xmlNewChild(ptr, 0, elem, str);    }}static int match_element(xmlNodePtr ptr, const char *elem){    if (ptr->type == XML_ELEMENT_NODE && !strcmp(ptr->name, elem))        return 1;    return 0;}#define CHECK_TYPE 0static int match_xsd_string_n(xmlNodePtr ptr, const char *elem, ODR o,                              char **val, int *len){#if CHECK_TYPE    struct _xmlAttr *attr;#endif    if (!match_element(ptr, elem))        return 0;#if CHECK_TYPE    for (attr = ptr->properties; attr; attr = attr->next)        if (!strcmp(attr->name, "type") &&            attr->children && attr->children->type == XML_TEXT_NODE)        {            const char *t = strchr(attr->children->content, ':');            if (t)                t = t + 1;            else                t = attr->children->content;            if (!strcmp(t, "string"))                break;        }    if (!attr)        return 0;#endif    ptr = ptr->children;    if (!ptr || ptr->type != XML_TEXT_NODE)        return 0;    *val = odr_strdup(o, ptr->content);    if (len)        *len = strlen(ptr->content);    return 1;}static int match_xsd_string(xmlNodePtr ptr, const char *elem, ODR o,                            char **val){    return match_xsd_string_n(ptr, elem, o, val, 0);}static int match_xsd_XML_n(xmlNodePtr ptr, const char *elem, ODR o,                           char **val, int *len){    xmlBufferPtr buf;    if (!match_element(ptr, elem))        return 0;    ptr = ptr->children;    if (!ptr)        return 0;    buf = xmlBufferCreate();    xmlNodeDump(buf, ptr->doc, ptr, 0, 0);    *val = odr_malloc(o, buf->use+1);    memcpy (*val, buf->content, buf->use);    (*val)[buf->use] = '\0';    if (len)        *len = buf->use;    xmlBufferFree(buf);    return 1;}                     static int match_xsd_integer(xmlNodePtr ptr, const char *elem, ODR o, int **val){#if CHECK_TYPE    struct _xmlAttr *attr;#endif    if (!match_element(ptr, elem))        return 0;#if CHECK_TYPE    for (attr = ptr->properties; attr; attr = attr->next)        if (!strcmp(attr->name, "type") &&            attr->children && attr->children->type == XML_TEXT_NODE)        {            const char *t = strchr(attr->children->content, ':');            if (t)                t = t + 1;            else                t = attr->children->content;            if (!strcmp(t, "integer"))                break;        }    if (!attr)        return 0;#endif    ptr = ptr->children;    if (!ptr || ptr->type != XML_TEXT_NODE)        return 0;    *val = odr_intdup(o, atoi(ptr->content));    return 1;}static int yaz_srw_records(ODR o, xmlNodePtr pptr, Z_SRW_record **recs,                           int *num, void *client_data, const char *ns){    if (o->direction == ODR_DECODE)    {        int i;        xmlNodePtr ptr;        *num = 0;        for (ptr = pptr->children; ptr; ptr = ptr->next)        {            if (ptr->type == XML_ELEMENT_NODE &&                !strcmp(ptr->name, "record"))                (*num)++;        }        if (!*num)            return 1;        *recs = odr_malloc(o, *num * sizeof(**recs));        for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next, i++)        {            if (ptr->type == XML_ELEMENT_NODE &&                !strcmp(ptr->name, "record"))            {                xmlNodePtr rptr;                (*recs)[i].recordSchema = 0;                (*recs)[i].recordPacking = Z_SRW_recordPacking_string;                (*recs)[i].recordData_buf = 0;                (*recs)[i].recordData_len = 0;                (*recs)[i].recordPosition = 0;                for (rptr = ptr->children; rptr; rptr = rptr->next)                {                    if (match_xsd_string(rptr, "recordSchema", o,                                          &(*recs)[i].recordSchema))                        ;                    else if (match_xsd_string_n(rptr, "recordData", o,                                                 &(*recs)[i].recordData_buf,                                                &(*recs)[i].recordData_len))                        ;                    else if (match_xsd_XML_n(rptr, "recordXML", o,                                              &(*recs)[i].recordData_buf,                                             &(*recs)[i].recordData_len))                        (*recs)[i].recordPacking = Z_SRW_recordPacking_XML;                    else if (match_xsd_integer(rptr, "recordPosition", o,                                                &(*recs)[i].recordPosition))                        ;                }            }        }    }    else if (o->direction == ODR_ENCODE)    {        int i;        for (i = 0; i < *num; i++)        {            xmlNodePtr rptr = xmlNewChild(pptr, 0, "record", 0);            add_xsd_string(rptr, "recordSchema", (*recs)[i].recordSchema);            switch((*recs)[i].recordPacking)            {            case Z_SRW_recordPacking_string:                add_xsd_string_n(rptr, "recordData", (*recs)[i].recordData_buf,                                 (*recs)[i].recordData_len);                break;            case Z_SRW_recordPacking_XML:                add_XML_n(rptr, "recordXML", (*recs)[i].recordData_buf,                          (*recs)[i].recordData_len);                break;            }            add_xsd_integer(rptr, "recordPosition", (*recs)[i].recordPosition);        }    }    return 0;}static int yaz_srw_diagnostics(ODR o, xmlNodePtr pptr, Z_SRW_diagnostic **recs,                               int *num, void *client_data, const char *ns){    if (o->direction == ODR_DECODE)    {        int i;        xmlNodePtr ptr;        *num = 0;        for (ptr = pptr->children; ptr; ptr = ptr->next)        {            if (ptr->type == XML_ELEMENT_NODE &&                !strcmp(ptr->name, "diagnostic"))                (*num)++;        }        if (!*num)            return 1;        *recs = odr_malloc(o, *num * sizeof(**recs));        for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next, i++)        {            if (ptr->type == XML_ELEMENT_NODE &&                !strcmp(ptr->name, "diagnostic"))            {                xmlNodePtr rptr;                (*recs)[i].code = 0;                (*recs)[i].details = 0;                for (rptr = ptr->children; rptr; rptr = rptr->next)                {                    if (match_xsd_integer(rptr, "code", o,                                                &(*recs)[i].code))                        ;                    else if (match_xsd_string(rptr, "details", o,                                               &(*recs)[i].details))                        ;                }                i++;            }        }    }    else if (o->direction == ODR_ENCODE)    {        int i;        for (i = 0; i < *num; i++)        {            xmlNodePtr rptr = xmlNewChild(pptr, 0, "diagnostic", 0);            add_xsd_integer(rptr, "code", (*recs)[i].code);            add_xsd_string(rptr, "details", (*recs)[i].details);        }    }    return 0;}int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data,                  void *client_data, const char *ns){    xmlNodePtr pptr = vptr;    if (o->direction == ODR_DECODE)    {        xmlNodePtr method = pptr->children;        while (method && method->type == XML_TEXT_NODE)            method = method->next;                if (!method || method->type != XML_ELEMENT_NODE)            return -1;        if (!strcmp(method->name, "searchRetrieveRequest"))        {            Z_SRW_PDU **p = handler_data;            xmlNodePtr ptr = method->children;            Z_SRW_searchRetrieveRequest *req;            *p = odr_malloc(o, sizeof(**p));            (*p)->which = Z_SRW_searchRetrieve_request;            req = (*p)->u.request = odr_malloc(o, sizeof(*req));            req->query_type = Z_SRW_query_type_cql;            req->query.cql = 0;            req->sort_type = Z_SRW_sort_type_none;            req->sort.none = 0;            req->startRecord = 0;            req->maximumRecords = 0;            req->recordSchema = 0;            req->recordPacking = 0;            req->database = 0;            for (; ptr; ptr = ptr->next)            {                if (match_xsd_string(ptr, "query", o,                                      &req->query.cql))                    req->query_type = Z_SRW_query_type_cql;                else if (match_xsd_string(ptr, "pQuery", o,                                      &req->query.pqf))                    req->query_type = Z_SRW_query_type_pqf;                else if (match_xsd_string(ptr, "xQuery", o,                                      &req->query.xcql))                    req->query_type = Z_SRW_query_type_xcql;                else if (match_xsd_string(ptr, "sortKeys", o,                                           &req->sort.sortKeys))                    req->sort_type = Z_SRW_sort_type_sort;                else if (match_xsd_string(ptr, "recordSchema", o,                                           &req->recordSchema))                    ;                else if (match_xsd_string(ptr, "recordPacking", o,                                          &req->recordPacking))                    ;                else if (match_xsd_integer(ptr, "startRecord", o,                                           &req->startRecord))                    ;                else if (match_xsd_integer(ptr, "maximumRecords", o,                                           &req->maximumRecords))                    ;                else if (match_xsd_string(ptr, "database", o,                                           &req->database))                    ;                /* missing is xQuery, xSortKeys .. */            }        }        else if (!strcmp(method->name, "searchRetrieveResponse"))        {            Z_SRW_PDU **p = handler_data;            xmlNodePtr ptr = method->children;            Z_SRW_searchRetrieveResponse *res;            *p = odr_malloc(o, sizeof(**p));            (*p)->which = Z_SRW_searchRetrieve_response;            res = (*p)->u.response = odr_malloc(o, sizeof(*res));            res->numberOfRecords = 0;            res->resultSetId = 0;            res->resultSetIdleTime = 0;            res->records = 0;            res->num_records = 0;            res->diagnostics = 0;            res->num_diagnostics = 0;            res->nextRecordPosition = 0;            for (; ptr; ptr = ptr->next)            {                if (match_xsd_integer(ptr, "numberOfRecords", o,                                       &res->numberOfRecords))                    ;                else if (match_xsd_string(ptr, "resultSetId", o,                                           &res->resultSetId))                    ;                else if (match_xsd_integer(ptr, "resultSetIdleTime", o,                                            &res->resultSetIdleTime))                    ;                else if (match_element(ptr, "records"))                    yaz_srw_records(o, ptr, &res->records,                                    &res->num_records, client_data,                                    ns);                else if (match_element(ptr, "diagnostics"))                    yaz_srw_diagnostics(o, ptr, &res->diagnostics,                                        &res->num_diagnostics,                                        client_data, ns);                else if (match_xsd_integer(ptr, "nextRecordPosition", o,                                           &res->nextRecordPosition))                    ;            }        }        else if (!strcmp(method->name, "explainRequest"))        {            Z_SRW_PDU **p = handler_data;            Z_SRW_explainRequest *req;                        *p = odr_malloc(o, sizeof(**p));            (*p)->which = Z_SRW_explain_request;            req = (*p)->u.explain_request = odr_malloc(o, sizeof(*req));            req->dummy = 0;        }        else if (!strcmp(method->name, "explainResponse"))        {            Z_SRW_PDU **p = handler_data;            Z_SRW_explainResponse *res;            xmlNodePtr ptr = method->children;            *p = odr_malloc(o, sizeof(**p));            (*p)->which = Z_SRW_explain_response;            res = (*p)->u.explain_response = odr_malloc(o, sizeof(*res));            res->explainData_buf = 0;            res->explainData_len = 0;            res->explainPacking = Z_SRW_recordPacking_string;            for (; ptr; ptr = ptr->next)            {                match_xsd_string_n(ptr, "Explain", o,                                    &res->explainData_buf,                                   &res->explainData_len);            }        }        else            return -1;    }    else if (o->direction == ODR_ENCODE)    {        Z_SRW_PDU **p = handler_data;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -