Exemplos de Serialização Windows C++

Exemplos de serialização de dados Windows C++ incluindo serialização/deserialização JSON e análise XML

💻 Serialização JSON cpp

🟡 intermediate ⭐⭐⭐

Converter objetos C++ em strings JSON e serializar estruturas de dados para formato JSON

⏱️ 25 min 🏷️ cpp, json, serialization, windows
Prerequisites: Intermediate C++, JSON basics, nlohmann/json library
// Windows C++ JSON Serialization Examples
// Using nlohmann/json library - modern C++ JSON library

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

// 1. Basic JSON Serialization
struct Person {
    std::string name;
    int age;
    std::string email;
    std::vector<std::string> hobbies;

    // Convert Person to JSON
    json toJson() const {
        json j;
        j["name"] = name;
        j["age"] = age;
        j["email"] = email;
        j["hobbies"] = hobbies;
        return j;
    }

    // Convert JSON to Person
    static Person fromJson(const json& j) {
        Person p;
        p.name = j["name"];
        p.age = j["age"];
        p.email = j["email"];
        p.hobbies = j["hobbies"].get<std::vector<std::string>>();
        return p;
    }
};

void basicJsonSerialization() {
    std::cout << "=== Basic JSON Serialization ===" << std::endl;

    Person person;
    person.name = "Alice Smith";
    person.age = 30;
    person.email = "[email protected]";
    person.hobbies = {"reading", "hiking", "photography"};

    // Serialize to JSON
    json j = person.toJson();
    std::string jsonString = j.dump(4); // 4-space indentation

    std::cout << "Serialized JSON:" << std::endl;
    std::cout << jsonString << std::endl;

    // Write to file
    std::ofstream file("person.json");
    file << std::setw(4) << j << std::endl;
    std::cout << "JSON saved to person.json" << std::endl;
}

// 2. JSON Serialization of Complex Objects
struct Address {
    std::string street;
    std::string city;
    std::string state;
    std::string zipCode;

    json toJson() const {
        return {
            {"street", street},
            {"city", city},
            {"state", state},
            {"zipCode", zipCode}
        };
    }
};

struct Employee {
    int id;
    std::string name;
    std::string department;
    double salary;
    Address address;
    std::vector<std::string> skills;
    std::map<std::string, std::string> metadata;

    json toJson() const {
        json j;
        j["id"] = id;
        j["name"] = name;
        j["department"] = department;
        j["salary"] = salary;
        j["address"] = address.toJson();
        j["skills"] = skills;
        j["metadata"] = metadata;
        return j;
    }

    std::string serialize() const {
        return toJson().dump(4);
    }
};

void complexObjectSerialization() {
    std::cout << "\n=== Complex Object Serialization ===" << std::endl;

    Employee emp;
    emp.id = 1001;
    emp.name = "John Doe";
    emp.department = "Engineering";
    emp.salary = 95000.00;

    emp.address = {
        "123 Tech Street",
        "San Francisco",
        "CA",
        "94102"
    };

    emp.skills = {"C++", "Python", "JavaScript", "SQL"};

    emp.metadata = {
        {"hire_date", "2020-01-15"},
        {"status", "active"},
        {"team", "backend"}
    };

    // Serialize to JSON string
    std::string jsonStr = emp.serialize();
    std::cout << "Serialized Employee:" << std::endl;
    std::cout << jsonStr << std::endl;
}

// 3. Serialize Collections to JSON
void serializeCollections() {
    std::cout << "\n=== Serialize Collections to JSON ===" << std::endl;

    // Vector of integers
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    json numbersJson = numbers;
    std::cout << "Numbers array: " << numbersJson.dump() << std::endl;

    // Map of strings
    std::map<std::string, std::string> config = {
        {"host", "localhost"},
        {"port", "8080"},
        {"database", "mydb"}
    };
    json configJson = config;
    std::cout << "Config object: " << configJson.dump(2) << std::endl;

    // Vector of Persons
    std::vector<Person> people;
    Person p1 = {"Alice", 28, "[email protected]", {"reading"}};
    Person p2 = {"Bob", 35, "[email protected]", {"gaming", "cooking"}};
    Person p3 = {"Charlie", 22, "[email protected]", {"sports"}};

    people.push_back(p1);
    people.push_back(p2);
    people.push_back(p3);

    json peopleJson = json::array();
    for (const auto& person : people) {
        peopleJson.push_back(person.toJson());
    }

    std::cout << "People array: " << peopleJson.dump(2) << std::endl;
}

// 4. Serialize with Custom Formatting
class JsonSerializer {
public:
    // Serialize with compact format (no whitespace)
    static std::string serializeCompact(const json& j) {
        return j.dump();
    }

    // Serialize with pretty printing
    static std::string serializePretty(const json& j, int indent = 4) {
        return j.dump(indent);
    }

    // Serialize with specific character escape handling
    static std::string serializeWithEscapes(const json& j) {
        return j.dump(-1, ' ', true); // ensure_ascii = true
    }

    // Serialize only specific fields
    template<typename T>
    static json serializeFields(const T& obj, const std::vector<std::string>& fields) {
        json fullJson = obj.toJson();
        json filteredJson;

        for (const auto& field : fields) {
            if (fullJson.contains(field)) {
                filteredJson[field] = fullJson[field];
            }
        }

        return filteredJson;
    }
};

void customFormattingSerialization() {
    std::cout << "\n=== Custom Formatting Serialization ===" << std::endl;

    Person person = {"David", 40, "[email protected]", {"music", "travel"}};
    json j = person.toJson();

    std::cout << "Compact format: " << JsonSerializer::serializeCompact(j) << std::endl;
    std::cout << "\nPretty format: " << JsonSerializer::serializePretty(j, 2) << std::endl;

    json filtered = JsonSerializer::serializeFields(person, {"name", "email"});
    std::cout << "\nFiltered fields: " << filtered.dump(2) << std::endl;
}

// 5. Serialize to File with Error Handling
class FileSerializer {
public:
    static bool serializeToFile(const json& j, const std::string& filename) {
        try {
            std::ofstream file(filename);
            if (!file.is_open()) {
                std::cerr << "Failed to open file: " << filename << std::endl;
                return false;
            }

            file << std::setw(4) << j << std::endl;
            file.close();

            std::cout << "Successfully serialized to " << filename << std::endl;
            return true;

        } catch (const std::exception& e) {
            std::cerr << "Error serializing to file: " << e.what() << std::endl;
            return false;
        }
    }

    static bool serializeWithBackup(const json& j, const std::string& filename) {
        // Check if file exists and create backup
        std::ifstream infile(filename);
        if (infile.good()) {
            std::string backupFilename = filename + ".bak";
            std::ifstream src(filename, std::ios::binary);
            std::ofstream dst(backupFilename, std::ios::binary);

            dst << src.rdbuf();

            std::cout << "Created backup: " << backupFilename << std::endl;
        }

        return serializeToFile(j, filename);
    }

    static bool appendToJsonFile(const std::string& key, const json& value, const std::string& filename) {
        json existingJson;

        // Try to read existing JSON
        std::ifstream infile(filename);
        if (infile.good()) {
            try {
                infile >> existingJson;
            } catch (const std::exception& e) {
                std::cerr << "Error reading existing JSON, creating new: " << e.what() << std::endl;
                existingJson = json::object();
            }
        } else {
            existingJson = json::object();
        }

        // Add or update the key
        existingJson[key] = value;

        // Write back to file
        return serializeToFile(existingJson, filename);
    }
};

void fileSerialization() {
    std::cout << "\n=== File Serialization ===" << std::endl;

    Employee emp = {
        1002,
        "Jane Smith",
        "Marketing",
        78000.00,
        {"456 Market St", "New York", "NY", "10001"},
        {"SEO", "Analytics", "Content"},
        {{"level", "senior"}, {"remote", "true"}}
    };

    json empJson = emp.toJson();
    FileSerializer::serializeToFile(empJson, "employee.json");
    FileSerializer::serializeWithBackup(empJson, "employee.json");

    // Append to configuration file
    json newConfig = {{"theme", "dark"}, {"fontSize", 14}};
    FileSerializer::appendToJsonFile("ui_settings", newConfig, "config.json");

    json serverConfig = {{"host", "api.example.com"}, {"timeout", 30}};
    FileSerializer::appendToJsonFile("api_config", serverConfig, "config.json");
}

// 6. Serialize Nested Structures
struct Product {
    int id;
    std::string name;
    double price;

    json toJson() const {
        return {{"id", id}, {"name", name}, {"price", price}};
    }
};

struct Order {
    int orderId;
    std::string orderDate;
    std::vector<Product> products;
    double totalAmount;

    json toJson() const {
        json productsArray = json::array();
        for (const auto& product : products) {
            productsArray.push_back(product.toJson());
        }

        return {
            {"orderId", orderId},
            {"orderDate", orderDate},
            {"products", productsArray},
            {"totalAmount", totalAmount}
        };
    }
};

struct Customer {
    int customerId;
    std::string name;
    std::vector<Order> orders;

    json toJson() const {
        json ordersArray = json::array();
        for (const auto& order : orders) {
            ordersArray.push_back(order.toJson());
        }

        return {
            {"customerId", customerId},
            {"name", name},
            {"orders", ordersArray}
        };
    }

    std::string serialize() const {
        return toJson().dump(4);
    }
};

void nestedStructureSerialization() {
    std::cout << "\n=== Nested Structure Serialization ===" << std::endl;

    Customer customer;
    customer.customerId = 5001;
    customer.name = "TechCorp Inc.";

    Order order1;
    order1.orderId = 10001;
    order1.orderDate = "2025-01-15";
    order1.products = {
        {1, "Laptop", 1299.99},
        {2, "Mouse", 29.99},
        {3, "Keyboard", 79.99}
    };
    order1.totalAmount = 1409.97;

    Order order2;
    order2.orderId = 10002;
    order2.orderDate = "2025-01-20";
    order2.products = {
        {4, "Monitor", 399.99},
        {5, "Webcam", 89.99}
    };
    order2.totalAmount = 489.98;

    customer.orders = {order1, order2};

    std::string customerJson = customer.serialize();
    std::cout << customerJson << std::endl;
}

// 7. Serialize with Validation
class ValidatedSerializer {
public:
    template<typename T>
    static bool serializeWithValidation(const T& obj, const std::string& filename) {
        try {
            json j = obj.toJson();

            // Validate JSON before writing
            if (!validateJson(j)) {
                std::cerr << "JSON validation failed" << std::endl;
                return false;
            }

            // Check file size limit (10MB)
            std::string jsonStr = j.dump();
            if (jsonStr.size() > 10 * 1024 * 1024) {
                std::cerr << "JSON exceeds size limit" << std::endl;
                return false;
            }

            return FileSerializer::serializeToFile(j, filename);

        } catch (const std::exception& e) {
            std::cerr << "Serialization error: " << e.what() << std::endl;
            return false;
        }
    }

private:
    static bool validateJson(const json& j) {
        // Check if JSON is valid (not null, not empty object/array)
        if (j.is_null()) {
            return false;
        }

        if (j.is_object() && j.empty()) {
            return false;
        }

        if (j.is_array() && j.empty()) {
            return false;
        }

        // Check for circular references (basic check)
        try {
            j.dump();
            return true;
        } catch (...) {
            return false;
        }
    }
};

void validatedSerialization() {
    std::cout << "\n=== Validated Serialization ===" << std::endl;

    Person person = {"Eve", 32, "[email protected]", {"painting"}};
    ValidatedSerializer::serializeWithValidation(person, "validated_person.json");
}

// 8. Serialize with Metadata
class MetadataSerializer {
public:
    template<typename T>
    static json serializeWithMetadata(const T& obj,
                                       const std::string& version = "1.0",
                                       const std::string& timestamp = "") {
        json wrapper;

        wrapper["_metadata"] = {
            {"version", version},
            {"timestamp", timestamp.empty() ? getCurrentTimestamp() : timestamp},
            {"type", typeid(T).name()}
        };

        wrapper["data"] = obj.toJson();

        return wrapper;
    }

    static std::string getCurrentTimestamp() {
        auto now = std::chrono::system_clock::now();
        auto time = std::chrono::system_clock::to_time_t(now);
        std::string timestamp = std::ctime(&time);
        timestamp.pop_back(); // Remove newline
        return timestamp;
    }
};

void metadataSerialization() {
    std::cout << "\n=== Metadata Serialization ===" << std::endl;

    Employee emp = {
        1003,
        "Mike Johnson",
        "Sales",
        65000.00,
        {"789 Commerce Ave", "Chicago", "IL", "60601"},
        {"Negotiation", "CRM"},
        {{"quota", "100000"}, {"region", "midwest"}}
    };

    json empWithMetadata = MetadataSerializer::serializeWithMetadata(emp, "2.0");
    std::cout << empWithMetadata.dump(4) << std::endl;
}

// Main demonstration
int main() {
    std::cout << "=== Windows C++ JSON Serialization Examples ===" << std::endl;

    basicJsonSerialization();
    complexObjectSerialization();
    serializeCollections();
    customFormattingSerialization();
    fileSerialization();
    nestedStructureSerialization();
    validatedSerialization();
    metadataSerialization();

    std::cout << "\n=== All JSON Serialization Examples Completed ===" << std::endl;
    return 0;
}

💻 Desserialização JSON cpp

🟡 intermediate ⭐⭐⭐⭐

Analisar strings JSON e convertê-las de volta em objetos C++ com tratamento de erros adequado

⏱️ 30 min 🏷️ cpp, json, deserialization, windows
Prerequisites: JSON serialization basics, Exception handling in C++
// Windows C++ JSON Deserialization Examples
// Using nlohmann/json library

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

// 1. Basic JSON Deserialization
struct Person {
    std::string name;
    int age;
    std::string email;
    std::vector<std::string> hobbies;

    // Convert JSON to Person
    static Person fromJson(const json& j) {
        Person p;
        if (j.contains("name") && j["name"].is_string()) {
            p.name = j["name"];
        }
        if (j.contains("age") && j["age"].is_number()) {
            p.age = j["age"];
        }
        if (j.contains("email") && j["email"].is_string()) {
            p.email = j["email"];
        }
        if (j.contains("hobbies") && j["hobbies"].is_array()) {
            p.hobbies = j["hobbies"].get<std::vector<std::string>>();
        }
        return p;
    }

    void display() const {
        std::cout << "Name: " << name << ", Age: " << age
                  << ", Email: " << email << std::endl;
        std::cout << "Hobbies: ";
        for (const auto& hobby : hobbies) {
            std::cout << hobby << " ";
        }
        std::cout << std::endl;
    }
};

void basicJsonDeserialization() {
    std::cout << "=== Basic JSON Deserialization ===" << std::endl;

    // Parse JSON string
    std::string jsonStr = R"(
        {
            "name": "Alice Smith",
            "age": 30,
            "email": "[email protected]",
            "hobbies": ["reading", "hiking", "photography"]
        }
    )";

    try {
        json j = json::parse(jsonStr);
        Person person = Person::fromJson(j);
        person.display();

    } catch (const json::parse_error& e) {
        std::cerr << "Parse error: " << e.what() << std::endl;
    } catch (const json::type_error& e) {
        std::cerr << "Type error: " << e.what() << std::endl;
    }
}

// 2. Deserialization from File
class JsonFileReader {
public:
    static json readFromFile(const std::string& filename) {
        std::ifstream file(filename);
        if (!file.is_open()) {
            throw std::runtime_error("Failed to open file: " + filename);
        }

        json j;
        try {
            file >> j;
        } catch (const json::parse_error& e) {
            file.close();
            throw std::runtime_error("JSON parse error: " + std::string(e.what()));
        }

        file.close();
        return j;
    }

    static bool readFromFileSafe(const std::string& filename, json& j) {
        try {
            j = readFromFile(filename);
            return true;
        } catch (const std::exception& e) {
            std::cerr << "Error reading file: " << e.what() << std::endl;
            return false;
        }
    }
};

void fileDeserialization() {
    std::cout << "\n=== File Deserialization ===" << std::endl;

    // First, create a sample JSON file
    json samplePerson = {
        {"name", "Bob Johnson"},
        {"age", 35},
        {"email", "[email protected]"},
        {"hobbies", {"gaming", "cooking", "travel"}}
    };

    std::ofstream outFile("person_data.json");
    outFile << std::setw(4) << samplePerson << std::endl;
    outFile.close();

    // Read from file
    try {
        json j = JsonFileReader::readFromFile("person_data.json");
        Person person = Person::fromJson(j);
        person.display();

    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
    }

    // Safe read with error handling
    json j;
    if (JsonFileReader::readFromFileSafe("person_data.json", j)) {
        std::cout << "Successfully read JSON from file" << std::endl;
    }
}

// 3. Deserialize Complex Objects
struct Address {
    std::string street;
    std::string city;
    std::string state;
    std::string zipCode;

    static Address fromJson(const json& j) {
        Address a;
        a.street = j.value("street", "");
        a.city = j.value("city", "");
        a.state = j.value("state", "");
        a.zipCode = j.value("zipCode", "");
        return a;
    }
};

struct Employee {
    int id;
    std::string name;
    std::string department;
    double salary;
    Address address;
    std::vector<std::string> skills;
    std::map<std::string, std::string> metadata;

    static Employee fromJson(const json& j) {
        Employee e;
        e.id = j.value("id", 0);
        e.name = j.value("name", "");
        e.department = j.value("department", "");
        e.salary = j.value("salary", 0.0);

        if (j.contains("address")) {
            e.address = Address::fromJson(j["address"]);
        }

        if (j.contains("skills") && j["skills"].is_array()) {
            e.skills = j["skills"].get<std::vector<std::string>>();
        }

        if (j.contains("metadata") && j["metadata"].is_object()) {
            e.metadata = j["metadata"].get<std::map<std::string, std::string>>();
        }

        return e;
    }

    void display() const {
        std::cout << "Employee ID: " << id << std::endl;
        std::cout << "Name: " << name << std::endl;
        std::cout << "Department: " << department << std::endl;
        std::cout << "Salary: $" << salary << std::endl;
        std::cout << "Address: " << address.street << ", " << address.city
                  << ", " << address.state << " " << address.zipCode << std::endl;
        std::cout << "Skills: ";
        for (const auto& skill : skills) {
            std::cout << skill << " ";
        }
        std::cout << std::endl;
    }
};

void complexObjectDeserialization() {
    std::cout << "\n=== Complex Object Deserialization ===" << std::endl;

    std::string jsonStr = R"(
        {
            "id": 1001,
            "name": "John Doe",
            "department": "Engineering",
            "salary": 95000.00,
            "address": {
                "street": "123 Tech Street",
                "city": "San Francisco",
                "state": "CA",
                "zipCode": "94102"
            },
            "skills": ["C++", "Python", "JavaScript", "SQL"],
            "metadata": {
                "hire_date": "2020-01-15",
                "status": "active",
                "team": "backend"
            }
        }
    )";

    try {
        json j = json::parse(jsonStr);
        Employee emp = Employee::fromJson(j);
        emp.display();

    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
    }
}

// 4. Deserialize Collections
void deserializeCollections() {
    std::cout << "\n=== Deserialize Collections ===" << std::endl;

    // Array of numbers
    std::string numbersJson = "[1, 2, 3, 4, 5]";
    json j1 = json::parse(numbersJson);
    std::vector<int> numbers = j1.get<std::vector<int>>();
    std::cout << "Numbers: ";
    for (int n : numbers) std::cout << n << " ";
    std::cout << std::endl;

    // Object with key-value pairs
    std::string configJson = R"(
        {
            "host": "localhost",
            "port": 8080,
            "database": "mydb"
        }
    )";
    json j2 = json::parse(configJson);
    std::map<std::string, std::string> config = j2.get<std::map<std::string, std::string>>();
    std::cout << "Config: " << std::endl;
    for (const auto& [key, value] : config) {
        std::cout << "  " << key << " = " << value << std::endl;
    }

    // Array of objects
    std::string peopleJson = R"(
        [
            {"name": "Alice", "age": 28, "email": "[email protected]"},
            {"name": "Bob", "age": 35, "email": "[email protected]"},
            {"name": "Charlie", "age": 22, "email": "[email protected]"}
        ]
    )";
    json j3 = json::parse(peopleJson);

    std::cout << "\nPeople array:" << std::endl;
    for (const auto& personJson : j3) {
        Person person = Person::fromJson(personJson);
        std::cout << "  - " << person.name << " (" << person.age << ")" << std::endl;
    }
}

// 5. Deserialization with Validation
class ValidatedDeserializer {
public:
    template<typename T>
    static bool deserializeWithValidation(const json& j, T& obj,
                                           const std::vector<std::string>& requiredFields = {}) {
        try {
            // Validate required fields
            for (const auto& field : requiredFields) {
                if (!j.contains(field)) {
                    std::cerr << "Missing required field: " << field << std::endl;
                    return false;
                }
            }

            // Perform type validation
            if (!validateTypes(j)) {
                std::cerr << "Type validation failed" << std::endl;
                return false;
            }

            obj = T::fromJson(j);
            return true;

        } catch (const std::exception& e) {
            std::cerr << "Deserialization error: " << e.what() << std::endl;
            return false;
        }
    }

    template<typename T>
    static bool deserializeFromFile(const std::string& filename, T& obj,
                                     const std::vector<std::string>& requiredFields = {}) {
        try {
            json j = JsonFileReader::readFromFile(filename);
            return deserializeWithValidation(j, obj, requiredFields);

        } catch (const std::exception& e) {
            std::cerr << "Error: " << e.what() << std::endl;
            return false;
        }
    }

private:
    static bool validateTypes(const json& j) {
        // Check for common type mismatches
        if (j.contains("age") && !j["age"].is_number()) {
            return false;
        }
        if (j.contains("salary") && !j["salary"].is_number()) {
            return false;
        }
        return true;
    }
};

void validatedDeserialization() {
    std::cout << "\n=== Validated Deserialization ===" << std::endl;

    std::string validJson = R"(
        {
            "name": "Valid User",
            "age": 30,
            "email": "[email protected]"
        }
    )";

    json j = json::parse(validJson);
    Person person;
    std::vector<std::string> required = {"name", "email"};

    if (ValidatedDeserializer::deserializeWithValidation(j, person, required)) {
        std::cout << "Successfully deserialized with validation" << std::endl;
        person.display();
    }

    // Test with missing required field
    std::string invalidJson = R"(
        {
            "name": "Invalid User"
        }
    )";

    json j2 = json::parse(invalidJson);
    Person person2;

    if (!ValidatedDeserializer::deserializeWithValidation(j2, person2, required)) {
        std::cout << "Correctly detected missing required field" << std::endl;
    }
}

// 6. Handle Missing Fields with Defaults
struct Product {
    int id;
    std::string name;
    double price;
    std::string description;
    int stock;
    bool available;

    static Product fromJsonWithDefaults(const json& j) {
        Product p;
        p.id = j.value("id", -1);
        p.name = j.value("name", "Unnamed Product");
        p.price = j.value("price", 0.0);
        p.description = j.value("description", "No description");
        p.stock = j.value("stock", 0);
        p.available = j.value("available", true);
        return p;
    }

    void display() const {
        std::cout << "Product: " << name << " (ID: " << id << ")" << std::endl;
        std::cout << "  Price: $" << price << std::endl;
        std::cout << "  Description: " << description << std::endl;
        std::cout << "  Stock: " << stock << std::endl;
        std::cout << "  Available: " << (available ? "Yes" : "No") << std::endl;
    }
};

void defaultValuesDeserialization() {
    std::cout << "\n=== Default Values Deserialization ===" << std::endl;

    // JSON with missing fields
    std::string partialJson = R"(
        {
            "id": 101,
            "name": "Widget",
            "price": 29.99
        }
    )";

    json j = json::parse(partialJson);
    Product product = Product::fromJsonWithDefaults(j);
    product.display();
}

// 7. Streaming Deserialization for Large Files
void streamingDeserialization() {
    std::cout << "\n=== Streaming Deserialization ===" << std::endl;

    // Create a sample large JSON file
    std::ofstream outFile("large_data.json");
    outFile << "[\n";
    for (int i = 0; i < 5; i++) {
        if (i > 0) outFile << ",\n";
        outFile << "  {"id": " << i << ", "name": "Item" << i << "", "value": " << (i * 10) << "}";
    }
    outFile << "\n]" << std::endl;
    outFile.close();

    // Read with streaming parser
    std::ifstream inFile("large_data.json");
    json j;
    inFile >> j;

    std::cout << "Read " << j.size() << " items from large JSON file" << std::endl;
    for (const auto& item : j) {
        std::cout << "  - " << item["name"] << ": " << item["value"] << std::endl;
    }
}

// Main demonstration
int main() {
    std::cout << "=== Windows C++ JSON Deserialization Examples ===" << std::endl;

    basicJsonDeserialization();
    fileDeserialization();
    complexObjectDeserialization();
    deserializeCollections();
    validatedDeserialization();
    defaultValuesDeserialization();
    streamingDeserialization();

    std::cout << "\n=== All JSON Deserialization Examples Completed ===" << std::endl;
    return 0;
}

💻 Análise XML cpp

🟡 intermediate ⭐⭐⭐⭐

Analisar documentos XML usando a biblioteca TinyXML, navegar na árvore XML e extrair dados

⏱️ 30 min 🏷️ cpp, xml, parsing, windows
Prerequisites: Intermediate C++, XML basics, TinyXML-2 library
// Windows C++ XML Parsing Examples
// Using TinyXML-2 library

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include "tinyxml2.h"

using namespace tinyxml2;

// 1. Basic XML Parsing
void basicXmlParsing() {
    std::cout << "=== Basic XML Parsing ===" << std::endl;

    // Create sample XML document
    const char* xmlContent = R"(
        <?xml version="1.0" encoding="UTF-8"?>
        <person>
            <name>Alice Smith</name>
            <age>30</age>
            <email>[email protected]</email>
        </person>
    )";

    XMLDocument doc;
    XMLError result = doc.Parse(xmlContent);

    if (result != XML_SUCCESS) {
        std::cerr << "XML parsing failed" << std::endl;
        return;
    }

    // Get root element
    XMLElement* root = doc.FirstChildElement("person");
    if (root == nullptr) {
        std::cerr << "Root element not found" << std::endl;
        return;
    }

    // Extract data
    XMLElement* nameElement = root->FirstChildElement("name");
    XMLElement* ageElement = root->FirstChildElement("age");
    XMLElement* emailElement = root->FirstChildElement("email");

    if (nameElement) {
        std::cout << "Name: " << nameElement->GetText() << std::endl;
    }
    if (ageElement) {
        std::cout << "Age: " << ageElement->GetText() << std::endl;
    }
    if (emailElement) {
        std::cout << "Email: " << emailElement->GetText() << std::endl;
    }
}

// 2. Parse XML from File
void parseXmlFromFile() {
    std::cout << "\n=== Parse XML from File ===" << std::endl;

    // Create sample XML file
    const char* xmlContent = R"(
        <?xml version="1.0" encoding="UTF-8"?>
        <catalog>
            <book id="1">
                <title>The C++ Programming Language</title>
                <author>Bjarne Stroustrup</author>
                <price>59.99</price>
                <category>Programming</category>
            </book>
            <book id="2">
                <title>Effective Modern C++</title>
                <author>Scott Meyers</author>
                <price>45.50</price>
                <category>Programming</category>
            </book>
        </catalog>
    )";

    std::ofstream outFile("books.xml");
    outFile << xmlContent;
    outFile.close();

    // Parse the file
    XMLDocument doc;
    XMLError result = doc.LoadFile("books.xml");

    if (result != XML_SUCCESS) {
        std::cerr << "Failed to load XML file: " << result << std::endl;
        return;
    }

    std::cout << "Successfully loaded books.xml" << std::endl;

    XMLElement* catalog = doc.FirstChildElement("catalog");
    if (catalog == nullptr) {
        std::cerr << "Catalog element not found" << std::endl;
        return;
    }

    // Iterate through books
    XMLElement* book = catalog->FirstChildElement("book");
    int bookCount = 0;

    while (book != nullptr) {
        bookCount++;

        // Get attributes
        const char* id = book->Attribute("id");

        // Get child elements
        XMLElement* title = book->FirstChildElement("title");
        XMLElement* author = book->FirstChildElement("author");
        XMLElement* price = book->FirstChildElement("price");
        XMLElement* category = book->FirstChildElement("category");

        std::cout << "\nBook #" << (id ? id : "unknown") << std::endl;
        if (title) std::cout << "  Title: " << title->GetText() << std::endl;
        if (author) std::cout << "  Author: " << author->GetText() << std::endl;
        if (price) std::cout << "  Price: $" << price->GetText() << std::endl;
        if (category) std::cout << "  Category: " << category->GetText() << std::endl;

        book = book->NextSiblingElement("book");
    }

    std::cout << "\nTotal books: " << bookCount << std::endl;
}

// 3. Parse Nested XML Structures
struct Address {
    std::string street;
    std::string city;
    std::string state;
    std::string zipCode;

    static Address fromXml(XMLElement* elem) {
        Address addr;
        if (elem == nullptr) return addr;

        XMLElement* street = elem->FirstChildElement("street");
        XMLElement* city = elem->FirstChildElement("city");
        XMLElement* state = elem->FirstChildElement("state");
        XMLElement* zip = elem->FirstChildElement("zipCode");

        if (street) addr.street = street->GetText();
        if (city) addr.city = city->GetText();
        if (state) addr.state = state->GetText();
        if (zip) addr.zipCode = zip->GetText();

        return addr;
    }

    void display() const {
        std::cout << street << ", " << city << ", " << state << " " << zipCode << std::endl;
    }
};

struct Employee {
    int id;
    std::string name;
    std::string department;
    double salary;
    Address address;
    std::vector<std::string> skills;

    static Employee fromXml(XMLElement* elem) {
        Employee emp;
        if (elem == nullptr) return emp;

        elem->QueryIntAttribute("id", &emp.id);

        XMLElement* name = elem->FirstChildElement("name");
        XMLElement* dept = elem->FirstChildElement("department");
        XMLElement* salary = elem->FirstChildElement("salary");
        XMLElement* addr = elem->FirstChildElement("address");
        XMLElement* skills = elem->FirstChildElement("skills");

        if (name) emp.name = name->GetText();
        if (dept) emp.department = dept->GetText();
        if (salary) emp.salary = std::stod(salary->GetText());
        if (addr) emp.address = Address::fromXml(addr);

        // Parse skills
        if (skills) {
            XMLElement* skill = skills->FirstChildElement("skill");
            while (skill != nullptr) {
                if (skill->GetText()) {
                    emp.skills.push_back(skill->GetText());
                }
                skill = skill->NextSiblingElement("skill");
            }
        }

        return emp;
    }

    void display() const {
        std::cout << "Employee ID: " << id << std::endl;
        std::cout << "Name: " << name << std::endl;
        std::cout << "Department: " << department << std::endl;
        std::cout << "Salary: $" << salary << std::endl;
        std::cout << "Address: ";
        address.display();
        std::cout << "Skills: ";
        for (const auto& skill : skills) {
            std::cout << skill << " ";
        }
        std::cout << std::endl;
    }
};

void parseNestedXml() {
    std::cout << "\n=== Parse Nested XML Structures ===" << std::endl;

    const char* xmlContent = R"(
        <?xml version="1.0" encoding="UTF-8"?>
        <company>
            <employee id="1001">
                <name>John Doe</name>
                <department>Engineering</department>
                <salary>95000.00</salary>
                <address>
                    <street>123 Tech Street</street>
                    <city>San Francisco</city>
                    <state>CA</state>
                    <zipCode>94102</zipCode>
                </address>
                <skills>
                    <skill>C++</skill>
                    <skill>Python</skill>
                    <skill>JavaScript</skill>
                </skills>
            </employee>
            <employee id="1002">
                <name>Jane Smith</name>
                <department>Marketing</department>
                <salary>78000.00</salary>
                <address>
                    <street>456 Market St</street>
                    <city>New York</city>
                    <state>NY</state>
                    <zipCode>10001</zipCode>
                </address>
                <skills>
                    <skill>SEO</skill>
                    <skill>Analytics</skill>
                </skills>
            </employee>
        </company>
    )";

    XMLDocument doc;
    if (doc.Parse(xmlContent) != XML_SUCCESS) {
        std::cerr << "Failed to parse XML" << std::endl;
        return;
    }

    XMLElement* company = doc.FirstChildElement("company");
    if (company == nullptr) return;

    XMLElement* empElem = company->FirstChildElement("employee");
    while (empElem != nullptr) {
        Employee emp = Employee::fromXml(empElem);
        std::cout << "\n--- Employee ---" << std::endl;
        emp.display();
        empElem = empElem->NextSiblingElement("employee");
    }
}

// 4. XML Parsing with Error Handling
class XmlParser {
public:
    static bool parseWithValidation(const std::string& filename, XMLDocument& doc) {
        XMLError result = doc.LoadFile(filename.c_str());

        switch (result) {
            case XML_SUCCESS:
                std::cout << "XML file loaded successfully" << std::endl;
                return true;

            case XML_ERROR_FILE_NOT_FOUND:
                std::cerr << "Error: File not found" << std::endl;
                return false;

            case XML_ERROR_FILE_COULD_NOT_BE_OPENED:
                std::cerr << "Error: Could not open file" << std::endl;
                return false;

            case XML_ERROR_PARSING_ELEMENT:
                std::cerr << "Error: Invalid XML element" << std::endl;
                return false;

            case XML_ERROR_PARSING_ATTRIBUTE:
                std::cerr << "Error: Invalid XML attribute" << std::endl;
                return false;

            default:
                std::cerr << "Error: Unknown XML parsing error (code: " << result << ")" << std::endl;
                return false;
        }
    }

    static std::string getElementText(XMLElement* elem, const std::string& defaultVal = "") {
        if (elem == nullptr || elem->GetText() == nullptr) {
            return defaultVal;
        }
        return elem->GetText();
    }

    static int getIntAttribute(XMLElement* elem, const char* name, int defaultVal = 0) {
        int value = defaultVal;
        if (elem != nullptr) {
            elem->QueryIntAttribute(name, &value);
        }
        return value;
    }
};

void errorHandlingXmlParsing() {
    std::cout << "\n=== XML Parsing with Error Handling ===" << std::endl;

    // Try to load non-existent file
    XMLDocument doc;
    if (!XmlParser::parseWithValidation("nonexistent.xml", doc)) {
        std::cout << "Correctly handled missing file" << std::endl;
    }

    // Create valid XML file
    const char* xmlContent = R"(
        <?xml version="1.0" encoding="UTF-8"?>
        <config>
            <setting name="timeout" value="30"/>
            <setting name="maxConnections" value="100"/>
        </config>
    )";

    std::ofstream outFile("config.xml");
    outFile << xmlContent;
    outFile.close();

    if (XmlParser::parseWithValidation("config.xml", doc)) {
        XMLElement* config = doc.FirstChildElement("config");
        if (config != nullptr) {
            XMLElement* setting = config->FirstChildElement("setting");
            while (setting != nullptr) {
                const char* name = setting->Attribute("name");
                const char* value = setting->Attribute("value");
                if (name && value) {
                    std::cout << name << " = " << value << std::endl;
                }
                setting = setting->NextSiblingElement("setting");
            }
        }
    }
}

// 5. Search and Filter XML Data
void searchXmlData() {
    std::cout << "\n=== Search and Filter XML Data ===" << std::endl;

    const char* xmlContent = R"(
        <?xml version="1.0" encoding="UTF-8"?>
        <library>
            <book>
                <title>Book A</title>
                <author>Author X</author>
                <year>2020</year>
                <genre>fiction</genre>
            </book>
            <book>
                <title>Book B</title>
                <author>Author Y</author>
                <year>2021</year>
                <genre>non-fiction</genre>
            </book>
            <book>
                <title>Book C</title>
                <author>Author X</author>
                <year>2019</year>
                <genre>fiction</genre>
            </book>
        </library>
    )";

    XMLDocument doc;
    doc.Parse(xmlContent);

    XMLElement* library = doc.FirstChildElement("library");
    if (library == nullptr) return;

    // Search for books by specific author
    std::string searchAuthor = "Author X";
    std::cout << "Books by " << searchAuthor << ":" << std::endl;

    XMLElement* book = library->FirstChildElement("book");
    while (book != nullptr) {
        XMLElement* author = book->FirstChildElement("author");
        if (author != nullptr && author->GetText() != nullptr) {
            if (std::string(author->GetText()) == searchAuthor) {
                XMLElement* title = book->FirstChildElement("title");
                if (title != nullptr) {
                    std::cout << "  - " << title->GetText() << std::endl;
                }
            }
        }
        book = book->NextSiblingElement("book");
    }

    // Filter by genre
    std::string searchGenre = "fiction";
    std::cout << "\n" << searchGenre << " books:" << std::endl;

    book = library->FirstChildElement("book");
    while (book != nullptr) {
        XMLElement* genre = book->FirstChildElement("genre");
        if (genre != nullptr && genre->GetText() != nullptr) {
            if (std::string(genre->GetText()) == searchGenre) {
                XMLElement* title = book->FirstChildElement("title");
                if (title != nullptr) {
                    std::cout << "  - " << title->GetText() << std::endl;
                }
            }
        }
        book = book->NextSiblingElement("book");
    }
}

// 6. XML Modification and Output
void modifyXml() {
    std::cout << "\n=== XML Modification ===" << std::endl;

    XMLDocument doc;

    // Create root element
    XMLElement* root = doc.NewElement("products");
    doc.InsertFirstChild(root);

    // Add product elements
    for (int i = 1; i <= 3; i++) {
        XMLElement* product = doc.NewElement("product");
        product->SetAttribute("id", i);

        XMLElement* name = doc.NewElement("name");
        name->SetText("Product " + std::to_string(i));
        product->InsertEndChild(name);

        XMLElement* price = doc.NewElement("price");
        price->SetText(10.0 * i);
        product->InsertEndChild(price);

        root->InsertEndChild(product);
    }

    // Save to file
    doc.SaveFile("products.xml");
    std::cout << "XML saved to products.xml" << std::endl;

    // Print to console
    XMLPrinter printer;
    doc.Print(&printer);
    std::cout << "\nGenerated XML:" << std::endl;
    std::cout << printer.CStr() << std::endl;
}

// Main demonstration
int main() {
    std::cout << "=== Windows C++ XML Parsing Examples ===" << std::endl;

    basicXmlParsing();
    parseXmlFromFile();
    parseNestedXml();
    errorHandlingXmlParsing();
    searchXmlData();
    modifyXml();

    std::cout << "\n=== All XML Parsing Examples Completed ===" << std::endl;
    return 0;
}