-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathxml_validator_app.cpp
More file actions
129 lines (107 loc) · 4.43 KB
/
xml_validator_app.cpp
File metadata and controls
129 lines (107 loc) · 4.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include "xml_validator_app.hpp"
#include "simple_error_handler.hpp"
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/sax2/XMLReaderFactory.hpp>
#include <xercesc/sax2/SAX2XMLReader.hpp>
#include <xercesc/sax/SAXParseException.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLUni.hpp>
#include <filesystem>
#include <memory>
#include <spdlog/logger.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/spdlog.h>
namespace {
// Helper function that converts std::string to XMLCh*
XMLCh* to_xml_ch(const std::string& s) {
return ::xercesc::XMLString::transcode(s.c_str());
}
} // anonymous namespace
namespace j2::xercesc {
xml_validator_app::xml_validator_app()
{
// Creating loggers for console color output
const std::string logger_name = "xml_validator";
auto sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
logger_ = std::make_shared<spdlog::logger>(logger_name, sink);
spdlog::register_logger(logger_);
}
void xml_validator_app::set_xml_path(const std::string& xml_path) {
xml_path_ = xml_path;
}
void xml_validator_app::set_xsd_path(const std::string& xsd_path) {
xsd_path_ = xsd_path;
}
xml_validator_result xml_validator_app::run() {
// XML/XSD path validation
if (xml_path_.empty() || xsd_path_.empty()) {
logger_->error("XML path or XSD path is not set.");
return xml_validator_result::file_not_found;
}
if (!std::filesystem::exists(xml_path_)) {
logger_->error("XML file does not exist: {}", xml_path_);
return xml_validator_result::file_not_found;
}
if (!std::filesystem::exists(xsd_path_)) {
logger_->error("XSD file does not exist: {}", xsd_path_);
return xml_validator_result::file_not_found;
}
try {
// Xerces-C++ Initialization (requires once per process)
::xercesc::XMLPlatformUtils::Initialize();
} catch (const ::xercesc::XMLException& e) {
char* message = ::xercesc::XMLString::transcode(e.getMessage());
logger_->error("XMLPlatformUtils::Initialize failed: {}", message);
::xercesc::XMLString::release(&message);
return xml_validator_result::init_failed;
}
xml_validator_result result = xml_validator_result::success;
// Create SAX2 XML parser (manual delete required)
::xercesc::SAX2XMLReader* parser =
::xercesc::XMLReaderFactory::createXMLReader();
try {
simple_error_handler error_handler(logger_);
parser->setErrorHandler(&error_handler);
parser->setContentHandler(&error_handler);
// Set verification and schema-related options
parser->setFeature(::xercesc::XMLUni::fgSAX2CoreValidation, true);
parser->setFeature(::xercesc::XMLUni::fgXercesSchema, true);
parser->setFeature(::xercesc::XMLUni::fgXercesSchemaFullChecking, true);
// Setting the location of the no-namespace schema
XMLCh* no_ns_location = to_xml_ch(xsd_path_);
parser->setProperty(
::xercesc::XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation,
no_ns_location);
::xercesc::XMLString::release(&no_ns_location);
// parsing XML files
XMLCh* xml_file = to_xml_ch(xml_path_);
parser->parse(xml_file);
::xercesc::XMLString::release(&xml_file);
if (error_handler.has_errors()) {
logger_->error("XML failed XSD schema validation.");
result = xml_validator_result::schema_validation_failed;
} else {
logger_->info("XML passed XSD schema validation.");
}
} catch (const ::xercesc::XMLException& e) {
char* message = ::xercesc::XMLString::transcode(e.getMessage());
logger_->error("XMLException occurred: {}", message);
::xercesc::XMLString::release(&message);
result = xml_validator_result::xml_exception;
} catch (const ::xercesc::SAXParseException& e) {
char* message = ::xercesc::XMLString::transcode(e.getMessage());
logger_->error("SAXParseException occurred: {}", message);
::xercesc::XMLString::release(&message);
result = xml_validator_result::sax_parse_exception;
} catch (...) {
logger_->error("Unknown exception occurred");
result = xml_validator_result::unknown_exception;
}
if (parser) {
delete parser;
}
// Xerces-C++ exit (paired with Initialize)
::xercesc::XMLPlatformUtils::Terminate();
return result;
}
} // namespace j2::xercesc