zoukankan      html  css  js  c++  java
  • Linux c使用gumbo库解析页面表单信息(三)

    前面说了那么多,终于说到如何解析html表单信息了。

    什么是表单信息呢,这里我们先要有一些概念:

    如上图,这是一个QQ注册页面,注册页面当中需要我们填的空其实就是一个表单信息。

    具体到html代码当中,如下

    <form action="action_page.php">
    First name:<br>
    <input type="text" name="firstname" value="Mickey">
    <br>
    Last name:<br>
    <input type="text" name="lastname" value="Mouse">
    <br><br>
    <input type="submit" value="Submit">
    </form> 

    (html摘自w3cschool)

    (上图摘自w3cschool)

    一般而言,表单信息的标签都为input标签,或是select标签。当我们要上传表单的时候,主要post给服务器的是表单标签当中的name和value属性,如果我们要解析表单的话,只要将这两个属性解析出来就好。
    在浏览器当中我们上传表单的过程大概是这样子的

    其实就是吧我们刚才填入表单的数据post到服务器。

    以下给出代码

    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <stdlib.h>
    #include <string.h>
    #include "gumbo.h"
    
    #define parse_h
    
    //检查select标签下被选中的option标签
    void find_selected(GumboNode *node,char * str_value)
    {
        GumboVector *children;
        GumboAttribute *value;
        GumboNode *child;
    
        int i;
        children=&node->v.element.children;
    
        if(str_value!=NULL)
        {
            for(i=0;i<children->length;i++)
        {
            child=((GumboNode*)children->data[i]);
    
            if(child->v.element.tag==GUMBO_TAG_OPTION)//检查其是否为option标签
            {
                if(gumbo_get_attribute(&child->v.element.attributes,"selected"))//检查option是否被选中
                {
                    if((value=gumbo_get_attribute(&child->v.element.attributes,"value"))!=NULL)//保存option标签的value值
                    {
                        strcpy(str_value,(char *)value->value);
                        return;
                    }else{
    
                        strcpy(str_value," ");
                        return;
                    }
                }
            }
        }
    
        strcpy(str_value," ");
    
    
        }
    
    
        return;
    
    
    }
    
    //解析表单信息,将结果添加到链表当中
    void findDataFormItem(GumboNode *node)
    {
        GumboVector *children;
        int i;
        GumboAttribute *name;
        GumboAttribute *value;
        GumboAttribute *type;
        GumboAttribute *checked;
        char str_value[100];
    
        if(header==NULL)
        {
            printf("header is null/n");
            return;
        }
    
        if(node->type!=GUMBO_NODE_ELEMENT) return;//如果节点不为元素节点就返回,至于什么是元素节点,请查找dom树的有关资料
    
        children=&node->v.element.children;//获取子节点
        if((node->v.element.tag==GUMBO_TAG_INPUT)&&(name=gumbo_get_attribute(&node->v.element.attributes,"name"))&&(value=gumbo_get_attribute(&node->v.element.attributes,"value")))//如果标签为input标签,并且有name和value属性
        {
    
            if((type=gumbo_get_attribute(&node->v.element.attributes,"type")))//检查input标签类型
            {
    
            //当input标签的类型为checkbox类型的时候,是有当checkbox被选中的时候,才将name和value添加到链表当中,其余,直接添加
                if(strcmp((char*)type->value,"checkbox"))
                {
                    
                    printf("name=%s
    ",(char *)name->value);
                    printf("value=%s
    ",(char *)value->value);
                }
                else
    
                {
                    if((checked=gumbo_get_attribute(&node->v.element.attributes,"checked")))
                    {
                        
                        printf("name=%s
    ",(char *)name->value);
                        printf("value=%s
    ",(char *)value->value);
                    }
                }
            }
    
    
    
    
    
        }
    
        if((node->v.element.tag==GUMBO_TAG_SELECT)&&
        (name=gumbo_get_attribute(&node->v.element.attributes,"name")))//如果标签为select标签,并且有name属性
        {
    
            find_selected(node,str_value);//检查select标签下的option标签,如果某个option标签的有selected属性(表示选项被选中),就将其value保存到链表当中
            
            printf("name=%s
    ",(char *)name->value);
            printf("value=%s
    ",str_value);
    
        }
    
    
        //递归扫描
        if(!(node->v.element.tag==GUMBO_TAG_SELECT))
        {
    
            for(i=0;i<children->length;++i)
            {
                findDataFormItem((GumboNode*)(children->data[i]),header);
    
    
            }
    
        }
    }
    
    
    //解析html表单数据,并且将表单标签的name和value数据保存到一个链表当中
    void ParseFormItems(char *htmlFile)
    {
    
    
        GumboOutput *DOMtree;
    
        
        DOMtree=gumbo_parse(htmlFile);//解析html数据成为一刻,dom树,要多了解的话应该查找一些有关html5 dom树的知识
    
        findDataFormItem(DOMtree->root);//解析表单信息
    
     
    
        gumbo_destroy_output(&kGumboDefaultOptions,DOMtree);//释放资源
    
    
    
    
    }

    大家一开始可能并不是十分了解gumbo解析html页面的逻辑,其实gumbo解析html页面也是根据dom树和html5的逻辑来的。

    推荐一个html5标准的参考资料https://html.spec.whatwg.org/multipage/



  • 相关阅读:
    JVM(5)之 GC之标记
    JVM(4)之 使用MAT排查堆溢出
    JVM(3) 之 内存分配与回收策略
    JVM(2)之 JAVA堆
    JVM(1)之 JAVA栈
    MySQL查询时报错Illegal mix of collations
    struts2 基础学习
    python3.4 + pycharm安装与使用
    Pycharm激活
    IntelliJ IDEA 2018.2激活
  • 原文地址:https://www.cnblogs.com/thegodofthunder/p/7237802.html
Copyright © 2011-2022 走看看