2024/11/22

PugiXML

PugiXML 是一個 C++ XML parser 函式庫,支援 DOM-like interface 與 XPATH 1.0 標準。 PugiXML 在是否容易使用、執行速度以及支援功能中取得良好的平衡,其中一個特點就是容易與其它程式整合, 將 pugixml.cpp, pugixml.hpp 與 pugiconfig.hpp 複製到原始碼目錄下就可以開始使用了。

下面是 tree.xml

<?xml version="1.0"?>
<mesh name="mesh_root">
    <!-- here is a mesh node -->
    some text
    <![CDATA[someothertext]]>
    some more text
    <node attr1="value1" attr2="value2" />
    <node attr1="value2">
        <innernode/>
    </node>
</mesh>
<?include somedata?>

下面是載入 XML 檔案的程式:

#include "pugixml.hpp"
#include <iostream>

int main() {
    pugi::xml_document doc;

    pugi::xml_parse_result result = doc.load_file("tree.xml");

    std::cout << "Load result: " << result.description()
              << ", mesh name: " << doc.child("mesh").attribute("name").value()
              << std::endl;
}

下面的程式使用 libcurl 自網站下載 ATOM XML 的資料, 下載以後使用 PugiXML 分析並且將 title 與 link 的資料儲存為 html 格式。

#include "pugixml.hpp"
#include <cstdio>
#include <cstdlib>
#include <curl/curl.h>
#include <fstream>
#include <iostream>

int get_rss(const char *url, const char *outfile) {
    FILE *feedfile = fopen(outfile, "w");

    if (!feedfile)
        return -1;

    CURL *curl = curl_easy_init();
    if (!curl)
        return -1;

    curl_easy_setopt(curl, CURLOPT_URL, url);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, feedfile);

    CURLcode res = curl_easy_perform(curl);
    if (res)
        return -1;
    curl_easy_cleanup(curl);
    fclose(feedfile);
    return 0;
}

int main(int argc, char *argv[]) {
    char *url = NULL;
    char *filename = NULL;
    char *outfile = NULL;
    if (argc == 4) {
        url = argv[1];
        filename = argv[2];
        outfile = argv[3];
    } else {
        printf("Not valid arguments.\n");
    }

    get_rss(url, filename);

    pugi::xml_document doc;
    pugi::xml_parse_result result = doc.load_file(filename);

    pugi::xpath_node_set title = doc.select_nodes("/feed/entry/title");
    pugi::xpath_node_set link =
        doc.select_nodes("/feed/entry/link[@rel='alternate']");

    std::ofstream ofile(outfile);

    pugi::xpath_node_set::const_iterator it1 = title.begin();
    pugi::xpath_node_set::const_iterator it2 = link.begin();
    while (it1 != title.end() && it2 != link.end()) {
        pugi::xpath_node node1 = *it1;
        pugi::xpath_node node2 = *it2;
        ofile << "<a href=\"" << node2.node().attribute("href").value() << "\">"
              << node1.node().text().get() << "</a><br>" << std::endl;

        it1++;
        it2++;
    }
    ofile.close();
}

參考連結

沒有留言:

張貼留言

注意:只有此網誌的成員可以留言。