目录

一 参考链接

二  运行结果

三 代码


一 参考链接

DOM Programming Guide (apache.org)

Xerces-c DOM XML文件的构造_xerces-c domimplementation-CSDN博客

Xerces-c库的使用-CSDN博客

二  运行结果

xercesc库保存XML功能实现-LMLPHP

三 代码


#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"));
        DOMDocument* doc = imp->createDocument(0, Transcode_1("root"), 0);

        DOMElement* node = doc->createElement(Transcode_1("node1"));
        node->setAttribute(Transcode_1("name"), Transcode_1("node1"));
        node->setTextContent(Transcode_1("中文名字node1"));

        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);

        DOMLSOutput* output = dynamic_cast<DOMImplementationLS*>(imp)->createLSOutput();

        DOMLSSerializer* serial = dynamic_cast<DOMImplementationLS*>(imp)->createLSSerializer();

        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();
        output->setByteStream(myFormTarget);

        LocalFileFormatTarget* target = new LocalFileFormatTarget("a中文.xml");

        output->setByteStream(target);
        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
03-21 07:31