Skip to content

Instantly share code, notes, and snippets.

@Nkawu
Last active March 25, 2025 06:02
Show Gist options
  • Save Nkawu/a2390f26b031dad7347920cfbe7bc4a5 to your computer and use it in GitHub Desktop.
Save Nkawu/a2390f26b031dad7347920cfbe7bc4a5 to your computer and use it in GitHub Desktop.
c++ examples
mkdir build
cd build
cmake ..
make
ctest
cmake_minimum_required(VERSION 3.10)
project(XercesBoostExample)
find_package(Boost REQUIRED)
find_package(XercesC REQUIRED)
add_executable(XercesBoostExample main.cpp)
target_include_directories(XercesBoostExample PRIVATE ${Boost_INCLUDE_DIRS} ${XercesC_INCLUDE_DIRS})
target_link_libraries(XercesBoostExample PRIVATE ${Boost_LIBRARIES} XercesC::XercesC)
cmake_minimum_required(VERSION 3.10)
project(XMLParserTest)
find_package(XercesC REQUIRED)
find_package(Boost REQUIRED)
find_package(GTest REQUIRED)
include_directories(${XERCESC_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ${GTEST_INCLUDE_DIRS})
add_executable(xml_parser_test xml_parser_test.cpp)
target_link_libraries(xml_parser_test ${XERCESC_LIBRARIES} ${Boost_LIBRARIES} gtest gtest_main)
cmake_minimum_required(VERSION 3.10)
project(XercesBoostGTestExample)
find_package(Boost REQUIRED)
find_package(XercesC REQUIRED)
find_package(GTest REQUIRED)
add_executable(XercesBoostGTestExample main.cpp)
target_include_directories(XercesBoostGTestExample PRIVATE ${Boost_INCLUDE_DIRS} ${XercesC_INCLUDE_DIRS} ${GTEST_INCLUDE_DIRS})
target_link_libraries(XercesBoostGTestExample PRIVATE ${Boost_LIBRARIES} XercesC::XercesC GTest::GTest GTest::Main)
enable_testing()
add_test(NAME XMLParserTest COMMAND XercesBoostGTestExample)
<?xml version="1.0" encoding="UTF-8"?>
<root>
<child>Example Content</child>
</root>
#include <iostream>
#include <boost/algorithm/string.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/util/XMLString.hpp>
#include <gtest/gtest.h>
using namespace xercesc;
std::string XMLChToString(const XMLCh* xmlChStr) {
char* charStr = XMLString::transcode(xmlChStr);
std::string result(charStr);
XMLString::release(&charStr);
return result;
}
class XMLParser {
public:
XMLParser() {
XMLPlatformUtils::Initialize();
}
~XMLParser() {
XMLPlatformUtils::Terminate();
}
std::string parseRootElement(const std::string& filename) {
XercesDOMParser parser;
parser.setValidationScheme(XercesDOMParser::Val_Always);
parser.setDoNamespaces(true);
parser.parse(filename.c_str());
DOMDocument* doc = parser.getDocument();
DOMElement* root = doc->getDocumentElement();
if (root) {
return XMLChToString(root->getTagName());
}
return "";
}
};
TEST(XMLParserTest, ParseRootElement) {
XMLParser parser;
std::string rootName = parser.parseRootElement("example.xml");
EXPECT_FALSE(rootName.empty());
boost::to_upper(rootName);
EXPECT_EQ(rootName, "ROOT");
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
#include <iostream>
#include <boost/algorithm/string.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/util/XMLString.hpp>
using namespace xercesc;
std::string XMLChToString(const XMLCh* xmlChStr) {
char* charStr = XMLString::transcode(xmlChStr);
std::string result(charStr);
XMLString::release(&charStr);
return result;
}
int main() {
try {
XMLPlatformUtils::Initialize();
} catch (const XMLException& e) {
std::cerr << "Error initializing Xerces-C++: " << XMLChToString(e.getMessage()) << std::endl;
return 1;
}
XercesDOMParser parser;
parser.setValidationScheme(XercesDOMParser::Val_Always);
parser.setDoNamespaces(true);
try {
parser.parse("example.xml");
DOMDocument* doc = parser.getDocument();
DOMElement* root = doc->getDocumentElement();
if (root) {
std::string rootName = XMLChToString(root->getTagName());
std::cout << "Root element: " << rootName << std::endl;
boost::to_upper(rootName);
std::cout << "Root element in uppercase: " << rootName << std::endl;
}
} catch (const XMLException& e) {
std::cerr << "XML Parsing Error: " << XMLChToString(e.getMessage()) << std::endl;
} catch (const DOMException& e) {
std::cerr << "DOM Error: " << XMLChToString(e.getMessage()) << std::endl;
}
XMLPlatformUtils::Terminate();
return 0;
}
#include <iostream>
#include <string>
#include <sstream>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/framework/StdOutFormatTarget.hpp>
#include <boost/lexical_cast.hpp>
#include <gtest/gtest.h>
XERCES_CPP_NAMESPACE_USE
class XMLParser {
public:
XMLParser() {
try {
XMLPlatformUtils::Initialize();
} catch (const XMLException& toCatch) {
char* message = XMLString::transcode(toCatch.getMessage());
std::cerr << "Error during initialization! :\n"
<< message << "\n";
XMLString::release(&message);
}
}
~XMLParser() {
XMLPlatformUtils::Terminate();
}
int parseAndExtractInt(const std::string& xmlString, const std::string& tagName) {
XercesDOMParser parser;
parser.setValidationScheme(XercesDOMParser::Val_Never);
parser.setDoNamespaces(false);
parser.setDoSchema(false);
parser.setLoadExternalDTD(false);
std::stringstream ss(xmlString);
MemBufInputSource inputSource((const XMLByte*)ss.str().c_str(), ss.str().length(), "in-memory");
parser.parse(inputSource);
DOMDocument* doc = parser.getDocument();
DOMNodeList* nodeList = doc->getElementsByTagName(XMLString::transcode(tagName.c_str()));
if (nodeList->getLength() > 0) {
DOMNode* node = nodeList->item(0);
DOMNode* textNode = node->getFirstChild();
if (textNode && textNode->getNodeType() == DOMNode::TEXT_NODE) {
char* value = XMLString::transcode(textNode->getNodeValue());
int result = boost::lexical_cast<int>(value);
XMLString::release(&value);
doc->release();
return result;
}
}
doc->release();
throw std::runtime_error("Tag not found or invalid content.");
}
};
TEST(XMLParserTest, ParseInt) {
XMLParser parser;
std::string xmlString = "<root><value>123</value></root>";
ASSERT_EQ(123, parser.parseAndExtractInt(xmlString, "value"));
}
TEST(XMLParserTest, TagNotFound) {
XMLParser parser;
std::string xmlString = "<root><value>123</value></root>";
ASSERT_THROW(parser.parseAndExtractInt(xmlString, "nonexistent"), std::runtime_error);
}
TEST(XMLParserTest, InvalidInt) {
XMLParser parser;
std::string xmlString = "<root><value>abc</value></root>";
ASSERT_THROW(parser.parseAndExtractInt(xmlString, "value"), boost::bad_lexical_cast);
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
mkdir build
cd build
cmake ..
make
./xml_parser_test

Explanation:

This example demonstrates how to use Xerces-C, Boost, and Google Test together in a C++ program.

Key Components:

  • Xerces-C:
    • The XMLParser class utilizes Xerces-C to parse XML strings.
    • XMLPlatformUtils::Initialize() and XMLPlatformUtils::Terminate() handle the initialization and cleanup of the Xerces-C library.
    • XercesDOMParser parses the XML input.
    • DOMDocument, DOMNodeList, and DOMNode are used to navigate and access elements within the XML document's structure.
    • XMLString::transcode() is essential for converting between Xerces-C's internal XMLCh* character type and standard char* strings.
  • Boost:
    • boost::lexical_cast is employed to safely convert the extracted XML text into an integer value.
  • Google Test:
    • The TEST macros define individual test cases, ensuring the XMLParser class functions correctly.
    • ASSERT_EQ is used to verify that the parsed integer matches the expected value.
    • ASSERT_THROW is used to confirm that the code throws the correct exceptions when encountering errors.
    • RUN_ALL_TESTS() initiates the execution of all defined test cases.
  • CMake:
    • CMake is used as the build system.
    • find_package() is used to locate the required libraries (Xerces-C, Boost, and Google Test).
    • include_directories() specifies the necessary header file paths.
    • add_executable() creates the executable for the test program.
    • target_link_libraries() links the executable with the required libraries.
  • Error Handling:
    • The code includes error-handling mechanisms to manage situations where XML tags are not found or when the extracted text cannot be converted into an integer.
  • In-Memory Parsing:
    • MemBufInputSource enables parsing XML directly from a string in memory, which is particularly useful for unit testing scenarios.
  • Resource Management:
    • The DOMDocument is explicitly released using doc->release() to prevent potential memory leaks.

How to Build and Run:

  1. Installation:
    • Ensure that Xerces-C, Boost, and Google Test are installed on your system. You might need to use your system's package manager or build them from source.
  2. CMakeLists.txt:
    • Create a CMakeLists.txt file with the provided CMake configuration.
  3. Build Process:
    • Create a build directory.
    • Navigate to the build directory.
    • Run cmake .. to generate the build files.
    • Run make to compile the code.
  4. Execution:
    • Execute the generated executable (e.g., ./xml_parser_test) to run the Google Test suite.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment