· KLDP.org · KLDP.net · KLDP Wiki · KLDP BBS ·
kkt49/Xerces

NoSmoke:DeleteMe kkt49

Xerces

basic function

///////////////////////////////////////
//
// - Find Node
// - Save Node (XML File)
// - (Get, Set) NodeValue, Attribute
//
///////////////////////////////////////

#ifndef __XMLFUNC_HPP
#define __XMLFUNC_HPP

#define ENC_ISO8859_1 "ISO8859-1"

//dom
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/dom/DOMImplementationLS.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/dom/DOMNodeFilter.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>
#include <xercesc/framework/MemBufFormatTarget.hpp>
#include <xercesc/framework/LocalFileFormatTarget.hpp>

#include <xercesc/util/Base64.hpp>

#include <stdio.h>
#include <unistd.h>

#include <vector>
#include <string>
#include <assert.h>

#include <iostream>
#include <fstream>

#include "FilePath.hpp"

#include "DOMTreeErrorReporter.hpp"
#include "DOMPrintFilter.hpp"
#include "DOMPrintErrorHandler.hpp"

XERCES_CPP_NAMESPACE_USE

/////////////////////////////////
// Class
//
// XMLFunc
//
// - Common XML Function
/////////////////////////////////
class XMLFunc
{
public:
    XMLFunc ();
    ~XMLFunc ();
    DOMNode * getNode (DOMNode * node, const char * node_name);
    DOMNode * getNode (DOMNode * node, const char * node_name, const char * att_name, const char * att_value);
    DOMNode * getNodeOfAttr (DOMNode *node, const char * att_name);

    
    DOMNodeList * getNodeList (DOMNode * node);
    DOMNodeList * getNodeList (DOMNode * node, const char * node_name);
    vector <DOMNode *> getNodeList (DOMNode * node, const char * node_name, const char * att_name, const char * att_value);

    string getNodeValue (DOMNode * node);
    string getNodeName  (DOMNode * node);
    bool setNodeValue (DOMNode * node, const char * node_value);
    string getNodeXML (DOMNode * node);

    DOMNode * addNode (DOMNode * node, const char * node_name);
    DOMNode * addNode (DOMNode * node, const char * node_name, const char * node_value);
    DOMNode * addNodeOfAttr (DOMNode * node, const char * node_name);
    DOMNode * addComment (DOMNode * node, const char * comment);

    // Base64 encoding & decoding
    string BinToBase64 (string & data);
    string Base64ToBin (string & data);

    // extended function (using FilePath class)
    int saveDOM (DOMNode * node, const char * filename);
};

XMLFunc::XMLFunc ()
{
}

XMLFunc::~XMLFunc ()
{
}

/////////////////////////////////
//
// XMLFunc Member Function
//
/////////////////////////////////
//노드명 검색 (발견된 첫번째 노드)
DOMNode * XMLFunc::getNode (DOMNode * node, const char * node_name)
{
    DOMNode * cur_node = node;
    if (!cur_node)
    {
        cout << "getNode() err" << endl;
        cout << " : node = NULL, node_name = " << node_name << endl;
        return NULL;
    }

    if (cur_node->getNodeType () != DOMNode::ELEMENT_NODE)
    {
        cout << "getNode() err: ELEMENT_NODE 가아님" << endl;
        return NULL;
    }

    //---------------------------------------//
    XMLCh * tag_name = XMLString::transcode (node_name);
    DOMNodeList * node_list = ((DOMElement *)cur_node)->getElementsByTagName (tag_name);
    XMLString::release (&tag_name);

    DOMNode * ret_node = NULL;
    //ret_node = node_list->item (0);
    for (int i = 0; i < node_list->getLength(); i++)
    {
        ret_node = node_list->item (i);
        if (ret_node->getParentNode () != cur_node)
        {
            ret_node = NULL;
            continue;
        }
        break;
    }
    //---------------------------------------//

    if (ret_node == NULL)
    {
        cout << node_name << ": getNode() err: 발견되지 않음" << endl;
        return NULL;
    }
    return ret_node;

}

//attribute 검색
DOMNode * XMLFunc::getNode (DOMNode * node, const char * node_name, const char * att_name, const char * att_value)
{
    //DOMNode * cur_node = node;
    if (!node)
    {
        cout << "getNode() err" << endl;
        cout << " : node = NULL, node_name = " << node_name << endl;
        return NULL;
    }

    if (node->getNodeType () != DOMNode::ELEMENT_NODE)
    {
        cout << "getNode() err: ELEMENT_NODE 가아님" << endl;
        return NULL;
    }

    XMLCh * tagName = XMLString::transcode (node_name);
    DOMNodeList * node_list = ((DOMElement *)node)->getElementsByTagName (tagName);
    XMLString::release (&tagName);

    XMLCh * attValue = XMLString::transcode (att_value);
    DOMNode * ret_node = NULL;

    XMLCh attName [100];

    for (int i = 0; i < node_list->getLength(); i++)
    {
        DOMNode * cur_node = node_list->item (i);
        if (cur_node->getParentNode () != node)
            continue;

        XMLString::transcode (att_name, attName, 99);
        const XMLCh * attValue2 = ((DOMElement *)cur_node)->getAttribute (attName);
        if (XMLString::compareString (attValue, attValue2) == 0)
        {
            ret_node = ((DOMElement *)cur_node)->getAttributeNode (attName);
            XMLString::release (&attValue);
            return ret_node;
        }

    }
    XMLString::release (&attValue);

    if (ret_node == NULL)
    {
        cout << node_name << ": getNode() err: 발견되지 않음" << endl;
    }
    return ret_node;

}

DOMNode * XMLFunc::getNodeOfAttr (DOMNode *node, const char * att_name)
{
    DOMNode * cur_node = node;
    if (!cur_node)
    {
        cout << "getNodeOfAttr() err: NULL node" << endl;
        assert (cur_node);
    }
    DOMNamedNodeMap * atts = cur_node->getAttributes ();
    DOMNode * attNode = NULL;
    for (int i = 0; i < atts->getLength(); i++)
    {
        attNode = atts->item (i);
        char * attName = XMLString::transcode (attNode->getNodeName ());
        if (strcmp (attName, att_name) == 0)
        {
            XMLString::release (&attName);
            return attNode;
        }
        XMLString::release (&attName);
    }
    cout << att_name << ": getNodeOfAttr() err: 발견되지 않음" << endl;
    return NULL;
}

string XMLFunc::getNodeValue (DOMNode * node)
{
    DOMNode * cur_node = node;
    if (!cur_node)
    {
        cout << "getNodeValue() err: NULL node" << endl;
        assert (cur_node);
    }

    char * node_value;
    string value;
    if (cur_node->getNodeType () == DOMNode::ELEMENT_NODE)
    {
        if (!cur_node->hasChildNodes())
        {
            value = "";
        }
        else
        {
            node_value = XMLString::transcode (cur_node->getFirstChild()->getNodeValue ());
            value = node_value;
            XMLString::release (&node_value);
        }
    }
    else if (cur_node->getNodeType () == DOMNode::ATTRIBUTE_NODE)
    {
        node_value = XMLString::transcode (cur_node->getNodeValue ());
        value = node_value;
        XMLString::release (&node_value);
    }
    else
    {
        cout << "getNodeValue() err: NodeType is not (ELEMENT or ATTRIBUTE)" << endl;
    }
    return value;
}

string XMLFunc::getNodeName  (DOMNode * node)
{
    DOMNode * cur_node = node;
    if (!cur_node)
    {
        cout << "getNodeValue() err: NULL node" << endl;
        assert (cur_node);
    }

    char * node_name;
    string value;
    if (cur_node->getNodeType () == DOMNode::ELEMENT_NODE)
    {
        node_name = XMLString::transcode (cur_node->getNodeName ());
        value = node_name;
        XMLString::release (&node_name);
    }
    else if (cur_node->getNodeType () == DOMNode::ATTRIBUTE_NODE)
    {
        node_name = XMLString::transcode (cur_node->getNodeName ());
        value = node_name;
        XMLString::release (&node_name);
    }
    else
    {
        cout << "getNodeName() err: NodeType is not (ELEMENT or ATTRIBUTE)" << endl;
    }
    return value;
}

bool XMLFunc::setNodeValue (DOMNode * node, const char * value)
{

    DOMNode * cur_node = node;
    if (!cur_node)
    {
        cout << "getNodeValue() err: NULL node" << endl;
        assert (cur_node);
    }

    XMLCh * node_value;
    if (cur_node->getNodeType () == DOMNode::ELEMENT_NODE)
    {

        node_value = XMLString::transcode (value);
        if (!cur_node->hasChildNodes()) // append node
        {
            DOMText * textNode = (cur_node->getOwnerDocument())->createTextNode (node_value);
            ((DOMElement *)cur_node)->appendChild (textNode);
        }
        else //modify node
        {
            cur_node->getFirstChild()->setNodeValue (node_value);
        }
        XMLString::release (&node_value);
    }
    else if (cur_node->getNodeType () == DOMNode::ATTRIBUTE_NODE)
    {
        node_value = XMLString::transcode (value);
        cur_node->setNodeValue (node_value);
        XMLString::release (&node_value);
    }
    else
    {
        cout << "setNodeValue() err: NodeType is not (ELEMENT or ATTRIBUTE)" << endl;
        return false;
    }
    return true;
}

DOMNodeList *
XMLFunc::getNodeList (DOMNode * node, const char * node_name)
{
    DOMNode * cur_node = node;
    if (!cur_node)
    {
        cout << "getNode() err" << endl;
        cout << " : node = NULL, node_name = " << node_name << endl;
        return NULL;
    }

    if (cur_node->getNodeType () != DOMNode::ELEMENT_NODE)
    {
        cout << "getNode() err: ELEMENT_NODE 가아님" << endl;
        return NULL;
    }

    XMLCh * tag_name = XMLString::transcode (node_name);
    DOMNodeList * node_list = ((DOMElement *)cur_node)->getElementsByTagName (tag_name);
    XMLString::release (&tag_name);
    return node_list;
}

vector <DOMNode *> XMLFunc::getNodeList (DOMNode * node, const char * node_name, const char * att_name, const char * att_value)
{
    vector <DOMNode *> vect_node_list;
    if (!node)
    {
        cout << "getNode() err" << endl;
        cout << " : node = NULL, node_name = " << node_name << endl;
        return vect_node_list;
    }

    if (node->getNodeType () != DOMNode::ELEMENT_NODE)
    {
        cout << "getNode() err: ELEMENT_NODE 가아님" << endl;
        return vect_node_list;
    }

    XMLCh * tagName = XMLString::transcode (node_name);
    DOMNodeList * node_list = ((DOMElement *)node)->getElementsByTagName (tagName);
    XMLString::release (&tagName);

    XMLCh * attValue = XMLString::transcode (att_value);

    XMLCh attName [100];

    for (int i = 0; i < node_list->getLength(); i++)
    {
        DOMNode *cur_node = node_list->item (i);
        if (cur_node->getParentNode () != node)
            continue;
        XMLString::transcode (att_name, attName, 99);
        const XMLCh * attValue2 = ((DOMElement *)cur_node)->getAttribute (attName);
        if (XMLString::compareString (attValue, attValue2) == 0)
        {
            vect_node_list.push_back (cur_node);
        }

    }
    XMLString::release (&attValue);
    return vect_node_list;
}

DOMNodeList *
XMLFunc::getNodeList (DOMNode * node)
{
    DOMNode * cur_node = node;
    if (!cur_node)
    {
        cout << "getNodeList() err" << endl;
        cout << " : node = NULL" << endl;
        return NULL;
    }
    if (cur_node->getNodeType () != DOMNode::ELEMENT_NODE)
    {
        cout << "getNode() err: ELEMENT_NODE 가아님" << endl;
        return NULL;
    }

    XMLCh * tag_name = XMLString::transcode ("*");
    DOMNodeList * node_list = ((DOMElement *)cur_node)->getElementsByTagName (tag_name);
    XMLString::release (&tag_name);
    return node_list;
}

string XMLFunc::getNodeXML (DOMNode * node)
{
    XMLCh tempStr[100];
    XMLString::transcode ("LS", tempStr, 99);
    DOMImplementation * impl = DOMImplementationRegistry::getDOMImplementation (tempStr);

    DOMWriter * writer = ((DOMImplementationLS*)impl)->createDOMWriter();
    XMLCh * pretty_format = XMLString::transcode ("format-pretty-print");
    writer->setFeature (pretty_format, true);
    XMLString::release (&pretty_format);

    MemBufFormatTarget * formTarget = new MemBufFormatTarget ();
    writer->writeNode (formTarget, *node);
    string xml = (const char *)formTarget->getRawBuffer();

    //formTarget->reset();
    delete formTarget;
    writer->release ();
    return xml;
}

int XMLFunc::saveDOM (DOMNode * node, const char * filename)
{
    FilePath file;
    string xml = getNodeXML (node);
    file.SaveFile (filename, xml.c_str(), xml.size(), 0755);
    return 0;
}

DOMNode * XMLFunc::addNode (DOMNode * node, const char * node_name, const char * node_value)
{

    XMLCh tempStr[100];
    XMLString::transcode (node_name, tempStr, 99);
    DOMElement * e = (node->getOwnerDocument())->createElement (tempStr);
    DOMNode * add_node = node->appendChild (e);
    setNodeValue (add_node, node_value);
    
    return add_node;
}

DOMNode * XMLFunc::addNode (DOMNode * node, const char * node_name)
{

    XMLCh tempStr[100];
    XMLString::transcode (node_name, tempStr, 99);
    DOMElement * e = (node->getOwnerDocument())->createElement (tempStr);
    DOMNode * add_node = node->appendChild (e);
    
    return add_node;
}

DOMNode * XMLFunc::addNodeOfAttr (DOMNode * node, const char * node_name)
{
    XMLCh tempStr[100];
    XMLString::transcode (node_name, tempStr, 99);
    DOMAttr * e = node->getOwnerDocument()->createAttribute (tempStr);
    ((DOMElement *)node)->setAttributeNode (e);
    DOMNode * ret_attr = getNodeOfAttr (node, node_name);
    return ret_attr;
}

DOMNode * XMLFunc::addComment (DOMNode * node, const char * comment)
{
    XMLCh * tempStr = XMLString::transcode (comment);
    DOMComment * e = node->getOwnerDocument()->createComment (tempStr);
    DOMNode * add_node = node->appendChild (e);
    XMLString::release (&tempStr);
    return add_node;
}

string XMLFunc::BinToBase64 (string & data)
{
    unsigned int length_en;
    char * img = (char *)Base64::encode ((XMLByte *)data.c_str(), data.size(), &length_en, 0);
    string base64 = img;
    XMLString::release (&img);
    return base64;
}

string XMLFunc::Base64ToBin (string & data)
{
    unsigned int len_out = 0;
    XMLByte * de_img = Base64::decode ((unsigned char *)data.c_str(), &len_out, 0);
    string bin = string ((char *)de_img, len_out);
    XMLString::release (&de_img);
    return bin;
}

#endif

Dom Parsing

#ifndef __XMLTRANS_HPP
#define __XMLTRANS_HPP

#include "XMLFunc.hpp"

/////////////////////////////////
// Class
//
// XMLTrans
//
// - Parsing XML
// - Make XML
/////////////////////////////////
class XMLTrans : public XMLFunc
{
private:
    MemBufInputSource * memBufIS;
    XercesDOMParser * parser;
    DOMImplementation * impl;
    DOMDocument * doc;
public:
    DOMNode * root;
    static int MemBufId;
    int err_count;

private:
    bool Parse (string & xml); // LoadXML ()

public:
    XMLTrans (); // 생성자
    virtual ~XMLTrans (); // 소멸자

    bool LoadXML (string & );
    DOMNode * createRoot (const char * root_name);
    // etc.

}; //class XMLTrans

//////////////////////////////////////
// XMLTrnas Static Member
int XMLTrans::MemBufId = 0;    //static
//////////////////////////////////////


/////////////////////////////////
//
// XMLTrans Member Function
//
/////////////////////////////////

XMLTrans::XMLTrans () //생성자
{
    memBufIS = NULL;
    parser = NULL;
    doc = NULL;
    root = NULL;
}

XMLTrans::~XMLTrans () //소멸자
{
    if (parser != NULL)
    {
        delete parser;
        //cout << "parser 객체 소멸" << endl;
        if (memBufIS != NULL)
        {
            delete memBufIS;
            //cout << "memBufIS 객체 소멸" << endl;
        }
    }
    else if (doc != NULL)
    {
        doc->release ();
        doc = NULL;
        //cout << "doc release() 소멸" << endl;
    }

}

//////////////////////////////////////////////////////
bool XMLTrans::Parse (string & xml)
{
    parser = new XercesDOMParser;

    char chId[10];
    sprintf (chId, "%d", MemBufId);
    
    memBufIS = new MemBufInputSource
    (
        (const XMLByte*)(xml).c_str()
        , (xml).size()
        , chId
        , false
    );

    ///////////////////////////
    //encoding 을 무조건 ISO8859-1로 바꿔준다.
    ///////////////////////////
    //XMLCh * enc = XMLString::transcode (ENC_ISO8859_1);
    XMLCh * enc = XMLString::transcode ("ISO8859-1");
    memBufIS->setEncoding (enc);
    XMLString::release (&enc);
    //parser->setDoSchema (XercesDOMParser::Val_Auto);
    //parser->setDoSchema (XercesDOMParser::Val_Always);
    //parser->setDoNamespaces (true);

    bool errorsOccured = false;
    try
    {
        ///////////////////////////
        // Parse
        ///////////////////////////
        parser->parse (*memBufIS);
    }
    catch (const XMLException& e)
    {
        cerr << "An err occurred during parsing\n Message: "
            << StrX (e.getMessage ()) << endl;
        errorsOccured = true;
        return false;
    }
    catch (const DOMException& e)
    {
        const unsigned int maxChars = 2047;
        XMLCh errText [maxChars + 1];

        cerr << "\nDOM Error during parsing \n"
            << "DOMException code is: " << e.code << endl;
        if (DOMImplementation::loadDOMExceptionMsg (e.code, errText, maxChars))
            cerr << "Message is: " << StrX (errText) << endl;
        errorsOccured = true;
        return false;
    }
    catch (...)
    {
        cerr << "An error occurred during parsing\n" << endl;
        errorsOccured = true;
        return false;
    }
    // non-wellformed XML
    err_count = parser->getErrorCount ();

    ///////////////////////////
    // DOMDocument
    ///////////////////////////
    doc = parser->getDocument ();
    root = doc->getDocumentElement ();
    return true;
}

bool XMLTrans::LoadXML (string & xml)
{
    if (parser != NULL)
    {
        delete parser;
        if (memBufIS != NULL)
        {
            delete memBufIS;
        }
    }
    else if (doc != NULL)
    {
        doc->release ();
        doc = NULL;
        //cout << "load xml release doc" << endl;
    }

    memBufIS = NULL;
    parser = NULL;
    doc = NULL;
    root = NULL;
    XMLPlatformUtils::atomicIncrement (MemBufId);

    if (!Parse (xml))
    {
        cout << "parse err" << endl;
        return false;
    }

    return true;
}

DOMNode * XMLTrans::createRoot (const char * root_name)
{
    if (parser != NULL)
    {
        delete parser;
        if (memBufIS != NULL)
        {
            delete memBufIS;
        }
    }
    else if (doc != NULL)
    {
        doc->release ();
        doc = NULL;
    }

    XMLCh tempStr[100];
    XMLString::transcode ("LS", tempStr, 99);
    impl = DOMImplementationRegistry::getDOMImplementation (tempStr);

    XMLString::transcode (root_name, tempStr, 99);
    doc = impl->createDocument (0, tempStr, 0);

    //XMLCh * enc = XMLString::transcode (ENC_ISO8859_1);
    XMLCh * enc = XMLString::transcode ("ISO8859-1");
    doc->setEncoding (enc);
    XMLString::release (&enc);

    root = doc->getDocumentElement ();

    return root;
}

#endif


ID
Password
Join
As goatheard learns his trade by goat, so writer learns his trade by wrote.


sponsored by andamiro
sponsored by cdnetworks
sponsored by HP

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2003-09-23 00:05:04
Processing time 0.0094 sec