LoginSignup
4
3

More than 5 years have passed since last update.

boost::property_tree::ptreeで読み込んだxmlを表示する

Posted at
a.cpp
#include <iostream>
#include <string>
#include <sstream>

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/lexical_cast.hpp>

std::string Xml = "\
<?xml version=\"1.0\" encoding=\"UTF-8\"?>\
<soapenv:Envelope xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\
        <soapenv:Body>\
                <soapenv:Fault>\
                        <faultcode>ServerFaultCode</faultcode>\
                        <faultstring>Cannot complete login due to an incorrect user name or password.</faultstring>\
                        <detail>\
                                <InvalidLoginFault xmlns=\"urn:vim25\" xsi:type=\"InvalidLogin\"></InvalidLoginFault>\
                        </detail>\
                </soapenv:Fault>\
        </soapenv:Body>\
</soapenv:Envelope>\
";

void show_xml(boost::property_tree::ptree &pt, int indent = 0);

void show_xml(boost::property_tree::ptree &pt, int indent) {
    for (auto &it : pt) {
        if (it.first == "<xmlattr>") {
            continue;
        }
        std::string attr;
        bool no_child = true;
        for (auto &itt : it.second.get_child("")) {
            if (itt.first == "<xmlattr>") {
                for (auto &ittt : itt.second.get_child("")) {
                    attr += " " + ittt.first + "=\"" + boost::lexical_cast<std::string>(ittt.second.data()) + "\"";
                }
                continue;
            }
            no_child = false;
        }
        for (int i = 0; i < indent; ++i) {
            std::cout << "\t";
        }
        std::cout << "<" << it.first << attr << ">";
        if (no_child) {
            std::cout << it.second.data();
        } else {
            std::cout << std::endl;
            show_xml(it.second, indent + 1);
            for (int i = 0; i < indent; ++i) {
                std::cout << "\t";
            }
        }
        std::cout << "</" << it.first << ">" << std::endl;
    }
}

int main(int, char **) {
    boost::property_tree::ptree pt;
    std::stringstream ss(Xml);
    boost::property_tree::read_xml(ss, pt);

    try {
        show_xml(pt);
    } catch (std::exception const &ex) {
        std::cout << "xml parse error." << std::endl;
    }

    return 0;
}

[root@localhost ~]#
[root@localhost ~]# g++ --std=c++11 a.cpp
[root@localhost ~]# ./a.out
<soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <soapenv:Body>
                <soapenv:Fault>
                        <faultcode>ServerFaultCode</faultcode>
                        <faultstring>Cannot complete login due to an incorrect user name or password.</faultstring>
                        <detail>
                                <InvalidLoginFault xmlns="urn:vim25" xsi:type="InvalidLogin"></InvalidLoginFault>
                        </detail>
                </soapenv:Fault>
        </soapenv:Body>
</soapenv:Envelope>
[root@localhost ~]#
[root@localhost ~]#

xmlattrの内容を確認して、attributeがちゃんと表示されるようにしたつもり。
(xmlattrを見ないで単にツリーをたどると、attributeが子ツリーとして表示されてしまう)

※すべてのxmlの内容が正しく表示できるかは、試していない。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3