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

```cpp: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の内容が正しく表示できるかは、試していない。