一 参考链接
DOM Programming Guide (apache.org)
Xerces-c DOM XML文件的构造_xerces-c domimplementation-CSDN博客
二 运行结果
三 代码
#if 1
//参考链接: https://blog.csdn.net/RGBMarco/article/details/81300814
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/framework/LocalFileFormatTarget.hpp>
#include <xercesc/dom/DOMImplementationRegistry.hpp>
#include <xercesc/dom/DOMImplementationLS.hpp>
#include <xercesc/dom/DOMLSSerializer.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/dom/DOMLSSerializerFilter.hpp>
#include <xercesc/dom/DOMError.hpp>
#include <xercesc/dom/DOMErrorHandler.hpp>
#include <xercesc/framework/XMLFormatter.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLString.hpp>
#include <fstream>
#include <iostream>
#define Transcode_1(x) XMLString::transcode(x)
#define Transcode_3(x,y,z) XMLString::transcode(x,y,z)
using namespace xercesc;
class MyDOMLSSerializerFilter : public xercesc::DOMLSSerializerFilter {
public:
// Constructor
MyDOMLSSerializerFilter() {
}
// Destructor
virtual ~MyDOMLSSerializerFilter() {
}
// 实现所有纯虚函数
/**
* Tells the DOMLSSerializer what types of nodes to show to the filter.
* See <code>DOMNodeFilter</code> for definition of the constants.
* The constant SHOW_ATTRIBUTE is meaningless here, attribute nodes will
* never be passed to a DOMLSSerializerFilter.
*
* @return The constants of what types of nodes to show.
* @since DOM Level 3
*/
ShowType getWhatToShow() const {
return 0;
};
// -----------------------------------------------------------------------
// Virtual DOMLSSerializerFilter interface
// -----------------------------------------------------------------------
/** @name Functions introduced in DOM Level 3 */
//@{
/**
* Interface from <code>DOMNodeFilter</code>,
* to be implemented by implementation (derived class)
*/
FilterAction acceptNode(const DOMNode* node) const {
std::cout << "acceptNode: " << std::endl;
return FilterAction::FILTER_ACCEPT;
};
};
class MyDOMErrorHandler : public xercesc::DOMErrorHandler {
public:
// Constructor
MyDOMErrorHandler() {
}
// Destructor
virtual ~MyDOMErrorHandler() {
}
// Handles a warning received from the parser
bool handleWarning(const xercesc::DOMError& domError) {
// Here you can implement your own logic to handle warnings
// For now, we just print the message and return true
std::cout << "Warning: " << xercesc::XMLString::transcode(domError.getMessage()) << std::endl;
return true;
}
// Handles an error received from the parser
bool handleError(const xercesc::DOMError& domError) {
// Here you can implement your own logic to handle errors
// For now, we just print the message and return false
std::cout << "Error: " << xercesc::XMLString::transcode(domError.getMessage()) << std::endl;
return false;
}
// Handles a fatal error received from the parser
bool handleFatalError(const xercesc::DOMError& domError) {
// Here you can implement your own logic to handle fatal errors
// For now, we just print the message and return false
std::cout << "Fatal Error: " << xercesc::XMLString::transcode(domError.getMessage()) << std::endl;
return false;
}
// Resets the error handler
void resetErrors() {
// Here you can implement your own logic to reset errors if needed
}
};
class StdOutFormatTarget : public xercesc::XMLFormatTarget {
public:
// -----------------------------------------------------------------------
// Virtual interface
// -----------------------------------------------------------------------
void writeChars(
const XMLByte* const toWrite
, const XMLSize_t count
, XMLFormatter* const formatter) {
};
void flush() {
};
};
int main()
{
try
{
//XMLPlatformUtils::Initialize();//en_US
XMLPlatformUtils::Initialize("zh_CN");
}
catch (const XMLException& toCatch)
{
std::cerr << Transcode_1(toCatch.getMessage());
}
try
{
//DOMImplementation* imp = DOMImplementationRegistry::getDOMImplementation(Transcode_1("Core"));
DOMImplementation* imp = DOMImplementationRegistry::getDOMImplementation(L"LS");
DOMLSOutput* output = dynamic_cast<DOMImplementationLS*>(imp)->createLSOutput();
DOMLSSerializer* serial = dynamic_cast<DOMImplementationLS*>(imp)->createLSSerializer();
output->setEncoding(L"UTF-8");
DOMLSSerializerFilter* filter = new MyDOMLSSerializerFilter();
serial->setFilter(filter);
// optionally you can implement your DOMErrorHandler (e.g. MyDOMErrorHandler)
// and set it to the serializer
DOMErrorHandler* errHandler = new MyDOMErrorHandler();
serial->getDomConfig()->setParameter(XMLUni::fgDOMErrorHandler, errHandler);
// StdOutFormatTarget prints the resultant XML stream
// to stdout once it receives any thing from the serializer.
XMLFormatTarget* myFormTarget = new StdOutFormatTarget();
const wchar_t* str = L"a中文.xml";
XMLFormatTarget* target = new LocalFileFormatTarget(str);
output->setByteStream(target);
// set user specified end of line sequence and output encoding
serial->setNewLine(L"\r");
// set serializer features
serial->getDomConfig()->setParameter(XERCES_CPP_NAMESPACE_QUALIFIER XMLUni::fgDOMWRTSplitCdataSections, false);
serial->getDomConfig()->setParameter(XERCES_CPP_NAMESPACE_QUALIFIER XMLUni::fgDOMWRTSplitCdataSections, false);
serial->getDomConfig()->setParameter(XERCES_CPP_NAMESPACE_QUALIFIER XMLUni::fgDOMWRTDiscardDefaultContent, false);
serial->getDomConfig()->setParameter(XERCES_CPP_NAMESPACE_QUALIFIER XMLUni::fgDOMWRTFormatPrettyPrint, true);//换行
serial->getDomConfig()->setParameter(XERCES_CPP_NAMESPACE_QUALIFIER XMLUni::fgDOMWRTBOM, false);
DOMDocument* doc = imp->createDocument(0, Transcode_1("root"), 0);
const wchar_t* strNode1 = L"node1中文";
DOMElement* node = doc->createElement(L"node1");
node->setAttribute(Transcode_1("name"), L"node1");
node->setTextContent(strNode1);
DOMElement* root = doc->getDocumentElement();
root->appendChild(node);
DOMElement* node2 = doc->createElement(Transcode_1("node2"));
node2->setAttribute(Transcode_1("name"), Transcode_1("node2"));
node2->setTextContent(Transcode_1("node2"));
root->appendChild(node2);
DOMElement* node2_1 = doc->createElement(Transcode_1("node2_1"));
node2_1->setAttribute(Transcode_1("name"), Transcode_1("node2_1"));
node2_1->setTextContent(Transcode_1("node2_1"));
node2->appendChild(node2_1);
DOMElement* node2_2 = doc->createElement(Transcode_1("node2_2"));
node2_2->setAttribute(Transcode_1("name"), Transcode_1("node2_2"));
node2_2->setTextContent(Transcode_1("node2_2"));
node2->appendChild(node2_2);
if (doc)
{
doc->setXmlStandalone(true);
serial->write(doc, output);
doc->release();
serial->release();
delete target;
}
}
catch (const DOMException& toCatch)
{
std::cerr << Transcode_1(toCatch.getMessage());
}
return 0;
}
#endif
#if 0
//https://blog.csdn.net/RGBMarco/article/details/81253563
#include <iostream>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/sax/SAXException.hpp>
#include <xercesc/sax/HandlerBase.hpp>
#include <string>
#include <vector>
using namespace std;
using namespace xercesc;
#define STUDENTS_TAG "Students"
#define STUDENT_TAG "Student"
#define NAME_TAG "Name"
#define AGE_TAG "Age"
#define SEX_TAG "Sex"
struct Student {
string Name;
int Age;
string Sex;
};
enum ErrorCode
{
LACK_BEGIN = 1, // 缺少<Students>标记
LACK_NAME = 2, // 缺少姓名
LACK_AGE = 3, // 缺少年龄
LACK_SEX = 4 // 缺少性别
};
DOMElement* findStudentsTag(DOMElement* root)
{
if (root == 0)
return 0;
if (XMLString::compareString(XMLString::transcode(root->getTagName()), STUDENTS_TAG) == 0)
return root;
else
return findStudentsTag(root->getNextElementSibling());
}
int visitDom2GetStudents(DOMElement* root, vector<Student>& students)
{
DOMElement* stustag = findStudentsTag(root);
if (stustag == 0)
return LACK_BEGIN;
DOMNodeList* stulist = root->getElementsByTagName(XMLString::transcode(STUDENT_TAG));
size_t length = stulist->getLength();
for (size_t index = 0; index < length; ++index)
{
DOMElement* elems = dynamic_cast<DOMElement*>(stulist->item(index));
DOMElement* name = elems->getFirstElementChild();
Student stu;
if (name == 0)
return LACK_NAME;
if (XMLString::compareString(XMLString::transcode(name->getTagName()), NAME_TAG) == 0)
{
DOMNode* n = dynamic_cast<DOMNode*>(name);
stu.Name = static_cast<string>(XMLString::transcode(n->getTextContent()));
}
else
return LACK_NAME;
DOMElement* age = name->getNextElementSibling();
if (age == 0)
return LACK_AGE;
if (XMLString::compareString(XMLString::transcode(age->getTagName()), AGE_TAG) == 0)
{
DOMNode* n = dynamic_cast<DOMNode*>(age);
stu.Age = atoi(XMLString::transcode(n->getTextContent()));
}
else
return LACK_AGE;
DOMElement* sex = age->getNextElementSibling();
if (sex == 0)
{
return LACK_SEX;
}
if (XMLString::compareString(XMLString::transcode(sex->getTagName()), SEX_TAG) == 0)
{
DOMNode* n = dynamic_cast<DOMNode*>(sex);
stu.Sex = static_cast<string>(XMLString::transcode(n->getTextContent()));
}
else
return LACK_SEX;
students.emplace_back(stu);
}
return 0;
}
int main()
{
try
{
XMLPlatformUtils::Initialize();
}
catch (const XMLException& toCatch)
{
std::cerr << XMLString::transcode(toCatch.getMessage());
return -1;
}
XercesDOMParser* parser = new XercesDOMParser();
ErrorHandler* errHandler = new HandlerBase();
parser->setErrorHandler(errHandler);
try
{
parser->parse("test.xml");
}
catch (const XMLException& toCatch)
{
std::cerr << XMLString::transcode(toCatch.getMessage());
return -1;
}
catch (const DOMException& toCatch)
{
std::cerr << XMLString::transcode(toCatch.getMessage());
return -1;
}
catch (const SAXException& toCatch)
{
std::cerr << XMLString::transcode(toCatch.getMessage());
return -1;
}
DOMDocument* doc = parser->getDocument();
DOMElement* root = doc->getDocumentElement();
vector<Student> students;
int ret = visitDom2GetStudents(root, students);
if (ret != 0)
std::cerr << "Parse error\n";
else
{
for (auto stu : students)
{
std::cout << "Name: " << stu.Name << "\n"
<< " Age: " << stu.Age << "\n"
<< " Sex: " << stu.Sex << "\n";
}
}
doc->release();
XMLPlatformUtils::Terminate();
return 0;
}
#endif