in extensions/windows-event-log/wel/JSONUtils.cpp [108:197]
rapidjson::Document toJSONImpl(const pugi::xml_node& root, bool flatten) {
rapidjson::Document doc{rapidjson::kObjectType};
auto event_xml = root.child("Event");
{
auto system_xml = event_xml.child("System");
auto& system = flatten ? doc : doc.AddMember("System", rapidjson::kObjectType, doc.GetAllocator())["System"];
{
auto provider_xml = system_xml.child("Provider");
auto& provider = flatten ? doc : system.AddMember("Provider", rapidjson::kObjectType, doc.GetAllocator())["Provider"];
provider.AddMember("Name", rapidjson::StringRef(provider_xml.attribute("Name").value()), doc.GetAllocator());
provider.AddMember("Guid", rapidjson::StringRef(provider_xml.attribute("Guid").value()), doc.GetAllocator());
}
system.AddMember("EventID", rapidjson::StringRef(system_xml.child("EventID").text().get()), doc.GetAllocator());
system.AddMember("Version", rapidjson::StringRef(system_xml.child("Version").text().get()), doc.GetAllocator());
system.AddMember("Level", rapidjson::StringRef(system_xml.child("Level").text().get()), doc.GetAllocator());
system.AddMember("Task", rapidjson::StringRef(system_xml.child("Task").text().get()), doc.GetAllocator());
system.AddMember("Opcode", rapidjson::StringRef(system_xml.child("Opcode").text().get()), doc.GetAllocator());
system.AddMember("Keywords", rapidjson::StringRef(system_xml.child("Keywords").text().get()), doc.GetAllocator());
{
auto timeCreated_xml = system_xml.child("TimeCreated");
auto& timeCreated = flatten ? doc : system.AddMember("TimeCreated", rapidjson::kObjectType, doc.GetAllocator())["TimeCreated"];
timeCreated.AddMember("SystemTime", rapidjson::StringRef(timeCreated_xml.attribute("SystemTime").value()), doc.GetAllocator());
}
system.AddMember("EventRecordID", rapidjson::StringRef(system_xml.child("EventRecordID").text().get()), doc.GetAllocator());
{
auto correlation_xml = system_xml.child("Correlation");
auto& correlation = flatten ? doc : system.AddMember("Correlation", rapidjson::kObjectType, doc.GetAllocator())["Correlation"];
const auto activity_id = correlation_xml.attribute("ActivityID");
if (!activity_id.empty()) {
correlation.AddMember("ActivityID", rapidjson::StringRef(activity_id.value()), doc.GetAllocator());
}
}
{
auto execution_xml = system_xml.child("Execution");
auto& execution = flatten ? doc : system.AddMember("Execution", rapidjson::kObjectType, doc.GetAllocator())["Execution"];
execution.AddMember("ProcessID", rapidjson::StringRef(execution_xml.attribute("ProcessID").value()), doc.GetAllocator());
execution.AddMember("ThreadID", rapidjson::StringRef(execution_xml.attribute("ThreadID").value()), doc.GetAllocator());
}
system.AddMember("Channel", rapidjson::StringRef(system_xml.child("Channel").text().get()), doc.GetAllocator());
system.AddMember("Computer", rapidjson::StringRef(system_xml.child("Computer").text().get()), doc.GetAllocator());
{
auto security_xml = system_xml.child("Security");
auto& security = flatten ? doc : system.AddMember("Security", rapidjson::kObjectType, doc.GetAllocator())["Security"];
security.AddMember("UserID", rapidjson::StringRef(security_xml.attribute("UserID").value()), doc.GetAllocator());
}
}
{
auto eventData_xml = event_xml.child("EventData");
if (flatten) {
for (const auto& event_data_child : eventData_xml.children()) {
std::string key = "EventData";
if (auto name_attr = event_data_child.attribute("Name"); !name_attr.empty()) {
key = utils::string::join_pack(key, ".", name_attr.value());
}
doc.AddMember(rapidjson::Value(createUniqueKey(key, doc), doc.GetAllocator()).Move(), rapidjson::StringRef(event_data_child.text().get()), doc.GetAllocator());
}
} else {
doc.AddMember("EventData", rapidjson::kArrayType, doc.GetAllocator());
for (const auto& event_data_child : eventData_xml.children()) {
auto name_attr = event_data_child.attribute("Name");
rapidjson::Value item(rapidjson::kObjectType);
item.AddMember("Name", rapidjson::StringRef(name_attr.value()), doc.GetAllocator());
item.AddMember("Content", rapidjson::StringRef(event_data_child.text().get()), doc.GetAllocator());
item.AddMember("Type", rapidjson::StringRef(event_data_child.name()), doc.GetAllocator());
doc["EventData"].PushBack(item, doc.GetAllocator()); // we need to re-query EventData because a reference to it wouldn't be stable
}
}
}
const auto userdata_xml = event_xml.child("UserData");
if (!userdata_xml.empty()) {
auto& userdata = flatten ? doc : doc.AddMember("UserData", rapidjson::kObjectType, doc.GetAllocator())["UserData"];
auto prefix = flatten ? std::optional("UserData.") : std::nullopt;
simplifiedGenericXmlToJson(userdata_xml, userdata, doc.GetAllocator(), prefix);
}
return doc;
}