How to convert XML to JSON in C++?

后端 未结 5 485
日久生厌
日久生厌 2021-01-24 08:00

I came across How to convert XML to JSON in ASP.NET C# (link) and one in javascript (at goessner.net/download/prj/jsonxml/). But have yet to find one in c++ that takes just a st

5条回答
  •  青春惊慌失措
    2021-01-24 08:46

    I implemented this function to convert xml to json using jsoncpp & rapidxml libraries, maybe will help someone. To compile : g++ -o xmltojson main.cpp -ljsoncpp. Tested on debian 9 only.

    #include 
    #include 
    #include 
    #include 
    
    #include 
    #include 
    
    void parse_node_tree(const rapidxml::xml_node<>* node, Json::Value& parent)
    {
        Json::Value obj(Json::objectValue);
    
        std::multiset array;
        for(rapidxml::xml_node<> *child = node->first_node(); child != nullptr; child = child->next_sibling())
        {
            if(child->type() != rapidxml::node_element)
                    continue;
    
            array.insert(child->name());
        }
    
        if(node->value_size() > 0)
        {
            obj["#text"] = node->value();
        }
    
        bool hasChilds = false;
    
        for(rapidxml::xml_attribute<> *attr = node->first_attribute(); attr != nullptr; attr = attr->next_attribute())
        {
            hasChilds = true;
            obj[attr->name()] = attr->value();
        }
    
        for(rapidxml::xml_node<> *child = node->first_node(); child != nullptr; child = child->next_sibling())
        {
            if(child->type() != rapidxml::node_element)
                       continue;
    
            hasChilds = true;
    
            Json::Value& next = obj[child->name()];
            if(array.count(child->name()) > 1 && !next.isArray())
            {
                    next = Json::arrayValue;
            }
    
            parse_node_tree(child, next);
        }
    
        // set result.
        if(parent.isArray())
        {
            parent.append(obj);
        }
        else
        {
            if(obj.isArray() || hasChilds)
                parent = obj;
            else
                parent = node->value();
        }
    }
    
    
    // convert xml string to json
    std::string xmltojson(const std::string& xml)
    {
        char xml_text[xml.size()+1];
    
        memset(xml_text, 0, xml.size());
        strncpy(xml_text, xml.c_str(), xml.size());
        xml_text[xml.size()] = '\0';
    
        rapidxml::xml_document<> doc;
    
        try
        {
                doc.parse<0>(xml_text);
        }
        catch(rapidxml::parse_error& exp)
        {
            std::cout << exp.what() << std::endl;
            return std::string();
        }
    
        rapidxml::xml_node<> *node = doc.first_node();
        if(node == nullptr)
            return std::string();
    
        Json::Value jdoc;
        Json::Value& jroot = jdoc[node->name()];
    
        parse_node_tree(node, jroot);
    
        Json::FastWriter fast_writer;
        return fast_writer.write(jdoc);
    }
    
    int main(int argc, char** argv)
    {
        // xml
        std::string test_xml = "Mercato di testGiovedi 18 dicembre 2003 16.05.295Miami American CafeIT07654930130Viale Carlo Espinasse 5, Como13302Filiberto GilardiIT87654770157    Via Biancospini 20, Messina8 1302EidonIT887511231Via Bassini 17/2, Milano18 202SkillNetIT887642131Via Chiasserini 11A, Milano2412EidonIT04835710965Via Cignoli 17/2, Roma11125Miami American CafeIT07654930130Viale Carlo Espinasse 5, Como13302Filiberto GilardiIT87654770157Via Biancospini 20, Messina81302EidonIT887511231Via Bassini 17/2, Milano18202SkillNetIT887642131Via Chiasserini 11A, Milano24202SkillNetIT887642131Via Chiasserini 11A, Milano2412EidonIT04835710965Via Cignoli 17/2, Roma1112";
    
        // convert
        std::string json = xmltojson(test_xml);
    
        // log
        std::cout << test_xml << std::endl;
        std::cout << std::endl;
        std::cout << json << std::endl;
    
        return 0;
    }
    

提交回复
热议问题