xercesc库中文保存XML功能实现

#include "XercesC_Test.h" #if 1 //参考链接: https://blog.****.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.****.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
上一篇:支持向量和非支持向量-一、支持向量


下一篇:ECharts5 概念篇1