1. fastcxmlXML 解析庫

        聯(lián)合創(chuàng)作 · 2023-09-29 22:39

        fastcxml 純 C 語言編寫的 XML 解析庫

        什么是fastcxml?

        fastcxml 是一款支持 XML 解析的多根節(jié)點的解析引擎,支持特性如下:

        • 支持多根 XML,一個 XML 文檔支持多個 ROOT 標(biāo)記,如下包含information 和 list

          <?xml version="1.0" encoding="UTF-8"?>
          <information>
              <name>Josin</name>
              <age>26</age>
              <address>Changsha</address>
          </information>
          
          <list>
          	<name>Linux</name>
          	<version>v5.0.1</version>
          	<tool>Git</tool>
          </list>
        • 支持XML文檔聲明,聲明必須位于第一行,以及眾多屬性,標(biāo)準(zhǔn)的XML聲明如下:

          <?xml version="1.0" encoding="UTF-8" author="Josin"?>
        • 支持標(biāo)記的屬性特性,如下面的 information 標(biāo)記包含的 id 和 pid 屬性:

          <?xml version="1.0" encoding="UTF-8"?>
          <information id="11" pid="99">
              <name>Josin</name>
              <age>26</age>
              <address>Changsha</address>
          </information>
        • 支持注釋,注意:注釋不可以嵌套

          <?xml version="1.0" encoding="UTF-8"?>
          <information id="11" pid="99">
              <!--<name>Josin</name>-->
              <age>2<!--6--></age>
              <address>Changsha</address>
          </information>
        • 支持 CDATA標(biāo)記 防止瀏覽器轉(zhuǎn)義

          <?xml version="1.0" encoding="UTF-8" author="Josin"?>
          <!--This is the comments-->
          <information>
              <name><![CDATA[Josin]]></name>
              <!--<age>26</age>-->
              <address>Hunan</address>
          </information>

        編譯 & 運行

        fastxml 可以在支持 C99標(biāo)準(zhǔn)的編譯器上編譯使用, 使用 cmake 編譯系統(tǒng),需要安裝 cmake 3.13 以及以上版本

        git clone https://gitee.com/josinli/fastxml.git
        cd fastxml
        mkdir build
        cd build
        cmake .. && make
        ./fastxml

        APIs 列表

        • 從字符串解析 XML,返回 NULL 表示XML文件格式錯誤
        CXML *new_cxml_from_string(char *str, unsigned long long);
        • 從CXML文件信息,解碼為字符串,返回的字符串需要通過 free 函數(shù)釋放
        char *new_string_from_cxml(CXML *c);
        • 釋放編碼后的 CXML 信息
        int   trash_cxml(CXML *v);

        快捷操作宏

        // 用來定義一個 CXML_n 的結(jié)構(gòu)來存儲解碼后的XML信息
        CXML_FIELD_DEF(n)
        // 中間使用 *aname 來定義一個節(jié)點名稱, 前面的 * 不能省略
        CXML_FIELD_DEF_END(n);
        // 用來聲明函數(shù),用來在其他的文件引入聲明
        CXML_FIELD_FUNC_DEF(n);
        // 上面的聲明的實現(xiàn)文件
        CXML_FIELD_FUNC(n)
          // 存在多個節(jié)點,信息,就定義多行
          // 第一個參數(shù)對應(yīng) XML的節(jié)點名稱,大小寫區(qū)分
          // 第二個參數(shù)對應(yīng)上面第一步 CXML_FIELD_DEF(n) 中定義的名稱,去掉前綴 *
          // 第三個參數(shù)對應(yīng)第一個參數(shù)的字符個數(shù)
          // 第四個參數(shù)可選 if 或者 elif 第一行必須為 if
          CXML_FIELD_CMP(name, aname, l, e)
        CXML_FIELD_FUNC_END();

        怎么快速在C語言或者C++操作XML?

        fastxml 自定了一系列的宏,來方便操作XML文檔,可以使用宏來快速完成XML文檔的解析與編碼,如下簡短示例,針對于下面的 XML文檔,我們來看看我們的解析過程:

        <?xml version="1.0" encoding="UTF-8" author="Josin" ?>
        <!--Hello This is the comments-->
        <info>
            <name><![CDATA[Josin]]></name>
            <address>Hunan</address>
        </info>

        操作流程如下:

        1. 新建 .h 和 .c 文件,如下命名為 xml_demo.c 和 xml_demo.h, 內(nèi)容如下:

          • xml_demo.h 文件內(nèi)容如下:
          #include <fc_xml.h>
          
          /**
           * @brief NOTICE
           * Simple example for using the macros
           */
          CXML_FIELD_DEF(root) /* 括號內(nèi)的info可以隨意填寫,如下相同 */
              *info /* 這里寫上需要解析的 同級XML 節(jié)點名稱,上面的xml最外層的只有一個 info節(jié)點,所以只有 *info */
          CXML_FIELD_DEF_END(root);
          CXML_FIELD_FUNC_DEF(root);
          • xml_demo.c 內(nèi)容如下:
          CXML_FIELD_FUNC(root)
              CXML_FIELD_CMP(info,    info,    4,   if) // 第一個宏參數(shù)表示的解析的節(jié)點名稱,如果在上面的宏里面定義了 CXML_FIELD_DEF里面需要解析到一個不同的變量,可以定義第二個別名參數(shù), 第三個參數(shù)表示的是第一個參數(shù)的字符長度, 最后一個可以使 if 或者 elif,第一個限制為if,后續(xù)的為 elif
          CXML_FIELD_FUNC_END(root);
        2. 在 main.c中開始解析過程:

          #include <stdio.h>
          #include <xml_demo.h>
          
          int main(int argc, char *argv[])
          {
              char *xml_str = "<?xml version=\"1.0\" encoding=\"UTF-8\" author=\"Josin\" ?>\n"
                              "<!--Hello This is the comments-->\n"
                              "<info>\n"
                              "    <name><![CDATA[Josin]]></name>\n"
                              "    <address>Hunan</address>\n"
                              "</info>";
              CXML *xml = new_cxml_from_string(xml_str, strlen(xml_str));
              
              if ( !xml ) {
                  printf("Your xml format is wrong.");
                  trash_cxml(xml);
                  return 0;
              }
              
              CXML_root *root = NEW_CXML_root_FROM_DATA(xml->data);
              printf("Root name: %s\n", root->info->key);
              TRASH_CXML_root(root);
              trash_cxml(xml);
          }

          輸出如下:

          Root name: info
        3. 因為這里的info節(jié)點是一個最外層的節(jié)點,它的值是一些子節(jié)點,所以如果需要解析他的子節(jié)點信息,需要重復(fù)上面的步驟,下面是一個整的示例,demo在demo目錄中:

        xml_demo.h 內(nèi)容如下:

        #include <fc_xml.h>
        
        /**
         * @brief NOTICE
         * Simple example for using the macros
         */
        CXML_FIELD_DEF(root)
            *info
        CXML_FIELD_DEF_END(root);
        CXML_FIELD_FUNC_DEF(root);
        
        CXML_FIELD_DEF(info)
            *name, *age, *addr
        CXML_FIELD_DEF_END(info);
        CXML_FIELD_FUNC_DEF(info);

        xml_demo.c 內(nèi)容如下:

        #include <xml_demo.h>
        
        
        /**
         * @brief NOTICE
         * Simple example for parsing the XML data
         */
        CXML_FIELD_FUNC(root)
            CXML_FIELD_CMP(info,   info,    4, elif)
        CXML_FIELD_FUNC_END();
        
        CXML_FIELD_FUNC(info)
            CXML_FIELD_CMP(name,    name,    4,   if)
            CXML_FIELD_CMP(address, addr,    7, elif)
        CXML_FIELD_FUNC_END();

        main.c 內(nèi)容如下:

        #include <stdio.h>
        #include <xml_demo.h>
        
        
        int main(int argc, char *argv[])
        {
            char *xml_str = "<?xml version=\"1.0\" encoding=\"UTF-8\" author=\"Josin\" ?>\n"
                            "<!--Hello This is the comments-->\n"
                            "<info>\n"
                            "    <name><![CDATA[Josin]]></name>\n"
                            "    <address>Hunan</address>\n"
                            "</info>";
            CXML *xml = new_cxml_from_string(xml_str, strlen(xml_str));
            
            if ( !xml ) {
                printf("Your xml format is wrong.");
                trash_cxml(xml);
                return 0;
            }
            
            CXML_root *root = NEW_CXML_root_FROM_DATA(xml->data);
            printf("Root name: %s\n", root->info->key);
            
            CXML_info *info = NEW_CXML_info_FROM_DATA(root->info->val);
        
            printf("%s: %s\n", info->name->key, (char *)info->name->val);
            printf("%s: %s\n", info->addr->key, (char *)info->addr->val);
        
            TRASH_CXML_info(info);
            TRASH_CXML_root(root);
            trash_cxml(xml);
            
            return 0;
        }
        瀏覽 18
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        編輯 分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        編輯 分享
        舉報
          
          

            1. 国产免费专区 | 一本大道AV伊人久久综合蜜芽 | 国产成人精品麻豆传奇 | 无码人妻精品一区二区蜜桃网站文 | 色com |